Detailed explanation of the difference between Android main project and R class in Module

  • 2021-08-21 21:16:27
  • OfStack

Preface

Everyone knows that in the Android project, the identities of all resource files in the project will be saved by automatically generating an R. java class. The resource declaration in R. java generated in the main project is a static constant, while in module it is a static variable. Why is this? We know that if a value is declared as a constant in java (modified by final), the constant is directly replaced with a value after compilation. In java syntax, the attributes of annotations and case expressions in switch-case must use constants or values directly, otherwise syntax errors will be reported.

Now we will discuss why the resource identifier declared in R class in module is not final, and what phenomena do these lead to? The following words are not much to say, let's take a look at the detailed introduction.

In the main project

For example, if you create a layout file of activity_main. xml in the main project, then R. java will automatically add a line of static constants as follows.


public static final class layout {
 ...
 public static final int activity_main=0x7f09001b;

You can then use the resource through R.layout.activity_main


public class MainActivity extends AppCompatActivity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 }
}

When we compile the above code, we get MainActivity. class, and we will find that the static constants in it are directly replaced by values. In the process of code running, you can find the corresponding resources directly through the value.


public class MainActivity extends AppCompatActivity {
 public MainActivity() {
 }

 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  this.setContentView(2131296283);
 }
}

In Module

Then we create an MainActivity and the corresponding resource in an module, and we look at R. java under that module.


public static final class layout {
 ...
 public static int activity_main = 0x7f0f001c;

Did everyone find the difference? This resource added in module is missing final. Let's look at the MainActivity. class file again. We will find that the resource reference here uses static variables instead of using the value of the resource directly.


public class MainActivity extends AppCompatActivity {
 public MainActivity() {
 }

 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  this.setContentView(layout.activity_main);
 }
}

Why do you do this

In Android, if you add a resource to module, take the example of activity_main. xml here. We assume here that if it is also final in module, what will happen? First, the resource will be replaced with a value in the compiled code of module; Second, when the module is added to the main project, if there is a resource with the same name in the main project, the resource in the module will be replaced; Third, an ID; will be generated again for this resource in the main project; Eventually, it will appear that the resource ID in module cannot be found. So, this is why the resource ID in module declares that it does not use final.

For the rules of resource merging, please refer to the official documents of google

https://developer.android.com/studio/write/add-resources.html.

Several phenomena caused by it

1. This is why module uses the resources of the main project when the main project has the same resources as module.

2. This is why we can't use switch-case for resources in module.

3. This is why we can't use butterknife directly in module, because the attributes of annotations need to be final. Of course, butterknife has provided a solution now. That is, one copy of R. java is named R2. java, and the resource declarations in R2. java are all final. This avoids grammar checking. Of course, the ByteCode compiled with butterknife uses the resource declaration in R. java.

Summarize


Related articles: