final field in R2.java in ButterKnife
Asked Answered
B

2

2

this is an extension of Android: Why do we need to use R2 instead of R with butterknife? and Reference in R.java not final

I understand that fields of R.java in the library project do not have final modifier to protect value collisions between library projects. However ButterKnife recovers final modifier in R2 and uses it.

I think this goes to the collision problem and values can collide, but there is no problem. How does it work?

===

I add examples. There are one main project and one library project. The main project has com.main.R and the library project has com.library.R.

  1. When there is a collision:
    • com.main.R: public static final int example = 0x1234
    • com.library.R: public static int example = 0x1234

if build tools does not recompile the library project, how can we avoid the collision between those values?

  1. When ButterKnife creates R2
    • com.main.R: public static final int example = 0x1234
    • com.library.R: public static int example = 0x1234
    • com.library.R2: public static final int example = 0x1234

com.library.R2 has a collision and even it has a final modifier. Doesn't it produce a problem? why?

Thanks

Bryonbryony answered 2/2, 2018 at 6:44 Comment(3)
Please note that final is not used in main R.java anymore. Refer this tools.android.com/tips/non-constant-fieldsBorder
@Border I really appreciate your help, but I have a difficulty to understand you. "final is not used in main R.java anymore" what does that mean? That document says final is removed only in case of library project.Bryonbryony
Actually yes, final in library projects is no longer accepted when they are mapped to the main R.java.Border
B
4

Although final keyword has been removed from the R.java generated class since it caused a negative impact on the build performance, Butterknife uses only final for itself which is why only the Butterknife code needs to be recompiled everytime a new id is to be added. The good point is Butterknife uses annotations in order to make sure that type that we return is always correct.

From the doc:

In other words, the constants are not final in a library project. The reason for this is simple: When multiple library projects are combined, the actual values of the fields (which must be unique) could collide. Before ADT 14, all fields were final, so as a result, all libraries had to have all their resources and associated Java code recompiled along with the main project whenever they were used. This was bad for performance, since it made builds very slow. It also prevented distributing library projects that didn't include the source code, limiting the usage scope of library projects.

The reason the fields are no longer final is that it means that the library jars can be compiled once and reused directly in other projects. As well as allowing distributing binary version of library projects (coming in r15), this makes for much faster builds.

Imagine If R.java was still supposed to contain the final keyword, for every library module that you've included in your android project, recompilation needed to be done since then R.java would be used by both the Android source code and libraries. Hence final keyword has been removed now. However, Butterknife still uses the final as it doesn't care about the clashes but BindView annotations internally use those type-annotations like @IdRes, @StringRes, @DrawableRes, etc inside that ensures the type safety of variables declared to be consistent.

Border answered 2/2, 2018 at 7:14 Comment(2)
Could you explain "Butterknife uses only final for itself which is why only the Butterknife code needs to be recompiled everytime a new id needs to be generated." again?Bryonbryony
I added examplesBryonbryony
B
1

I investigated further. In summary,

  • Resource values in library projects are reassigned when main project is built
  • "Final" needs to be removed to use reassigned values
  • Values in R2 is not reassigned so it might conflict, but it is only marker for Annotation. The actual value used when finding views comes from R

Details are here: https://battleshippark.wordpress.com/2018/02/12/butterknife-library-project-r2-final/

Bryonbryony answered 13/2, 2018 at 2:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.