这是Android: Why do we need to use R2 instead of R with butterknife?和Reference in R.java not final
的扩展我知道库项目中R.java的字段没有最终修饰符来保护库项目之间的价值冲突。但ButterKnife在R2中恢复了最终修饰符并使用它。
我认为这涉及到碰撞问题并且值可能会发生碰撞,但没有问题。它是如何工作的?
===
我添加了示例。 有一个主要项目和一个图书馆项目。主项目有com.main.R,库项目有com.library.R。
如果构建工具不重新编译库项目,我们如何避免这些值之间的冲突?
com.library.R2发生了碰撞,甚至还有一个最终修饰符。它不会产生问题吗?为什么呢?
谢谢
答案 0 :(得分:2)
虽然已从final
生成的类中删除了R.java
关键字,因为它对构建性能造成了负面影响,但Butterknife仅使用final
,这就是为什么只有Butterknife代码每次添加新ID时都需要重新编译。好点是Butterknife使用注释来确保我们返回的类型始终是正确的。
来自doc:
换句话说,常量在库项目中不是最终的。原因很简单:当组合多个库项目时,字段的实际值(必须是唯一的)可能会发生冲突。在ADT 14之前,所有字段都是最终字段,因此,所有库都必须在使用它们时将所有资源和相关Java代码与主项目一起重新编译。 这对性能不利,因为它使构建非常慢。它还阻止了分发没有包含源代码的库项目,限制了库项目的使用范围。
字段不再是最终的原因是它意味着库jar可以编译一次并直接在其他项目中重用。除了允许分发二进制版本的库项目(来自r15),这样可以更快地构建。
想象一下如果R.java
仍然应该包含final关键字,那么对于您在android项目中包含的每个库模块,需要重新编译,因为那时将使用R.java
通过Android源代码和库。因此,最终关键字已被删除。但是,Butterknife仍然使用final
因为它不关心冲突,但BindView
注释在内部使用那些类型注释,如@IdRes
,@StringRes
,{{ 1}}等内部确保声明一致的变量的类型安全。
答案 1 :(得分:0)
我进一步调查了。总之,
详细信息如下: https://battleshippark.wordpress.com/2018/02/12/butterknife-library-project-r2-final/