关于R.java和ButterKinfe独特的R2.java的那些事

关于R.java和ButterKinfe独特的R2.java的那些事

一、Android的R.java文件

  Android项目中,当Android应用程序被编译,会自动生成一个R类,包含了所有res/目录下资源的ID,如布局文件、资源文件、图片的ID等。
  即在Android项目中会通过自动生成一个R.java文件的方式来保存项目中所有资源文件的标识。在主项目中生成的R.java中的资源声明是一个静态常量,而在Module中却是一个静态变量
在这里插入图片描述

二、Android主项目和Module中R类的区别**

  1. Android主项目中的R类

  在主项目中创建一个资源文件或者控件ID等(例如activity_main.xml的布局文件),则R.java中会自动添加一行静态常量
  当通过R.layout.activity_main的方式使用资源,编译代码之后,静态常量会被直接替换成值。代码运行过程中,直接通过值来寻找对应的资源。
在这里插入图片描述

  1. Module中的R类

  在Module中添加资源后,R.java文件中自动添加的为静态变量而非静态常量。而这样也就导致了使用switch-case、注解以及凡是语法规定必须要用常量的地方都无法直接使用R.drawable。
  Android这样做的原因:如果在Module中添加了一个资源,假设R.java文件添加的是静态常量。那么就会导致如下三种问题。
  ① 该Module编译后的代码中该资源会被替换成值
  ② 该Module被添加到主项目中后,如果主项目中有一个同样名称的资源,那么Module中的该资源就会被替换
  ③ 主项目中会重新针对该资源生成一个ID,最终导致Module中的那个资源ID找不到;

三、ButterKnife独有的R2.java文件

  由于ButterKnife是一个依赖注入的框架,最为核心的使用方式就是使用注解进行依赖注入,而注解需要的属性是final的,因此为了解决这个问题,ButterKnife提供了一个解决方案:利用gradle拷贝一份R.java命名成R2.java,R2.java中的资源声明都是final,从而解决了Module中使用ButterKnife的问题。
在这里插入图片描述
  那么另一个问题来了:既然ButterKnife使用了R2.java中的资源声明是final,那么java complie的时候主项目中会重新对Module资源生成一个ID替换,那么为何实际运行中没有发生资源无法找到的问题?
  首先,每个Module各自打成aar的时候APPT会单独生成R.java,但是实际上Module在打成aar的时候是没有把R.java打进来的,相反却把R2.java打进aar了。
  其次,ButterKnife的APT生成的ViewBinding中取得的最终还是app生成的R.java中资源的ID。
  因此,总的来说就是,ButterKnife已经帮你搞定了这个问题,具体可以参照:R.java、R2.java是时候懂了中的ViewBind源码理解。
在这里插入图片描述

参考资料:Android主项目和Module中R类的区别
R.java、R2.java是时候懂了

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值