Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Android handle multiple R.java?

I'm making couple of Android library apps for a project. To simplify the question, let's say I have two libraries(utilLib, screenLib) in this project(now will be referred to as app).

There's String resource with the same name inside each project but with different values. Like this:

utilLib

<string name="app_version">1.0</string>
<string name="hello">UtilLib Hello</string>

screenLib

<string name="app_version">0.7a</string>
<string name="hello">ScreenLib Hello</string>

app

<string name="app_version">0.1</string>

I realized that I can refer to the string using com.package.R but what if my code looks like this what will show up?

<!-- language: java -->
import com.app.R; 
...

private void checkValue(){
    String version = getString(R.app_version);
    Log.d(TAG, "version: " + version); // 0.1 show be here
    String hello = getString(R.hello);
    Log.d(TAG, "Hello: " + hello); // <---- ? ('UtilLib Hello' or 'ScreenLib Hello')
}

I am trying to make modular build here but don't fully understand how Android prioritize its R.java to use. Has anyone had experienced with this?

like image 718
RobGThai Avatar asked Apr 23 '12 10:04

RobGThai


1 Answers

Log.d(TAG, "version: " + version); // 0.1 show be here

Reason quoting from official dev guide Managing Projects - Library Projects:

When you build an application that depends on a library project, the SDK tools compile the library into a temporary JAR file and uses it in the main project, then uses the result to generate the .apk. In cases where a resource ID is defined in both the application and the library, the tools ensure that the resource declared in the application gets priority and that the resource in the library project is not compiled into the application .apk. This gives your application the flexibility to either use or redefine any resource behaviors or values that are defined in any library.


Log.d(TAG, "Hello: " + hello); // <---- ? ('UtilLib Hello' or 'ScreenLib Hello')

This is determined by library project priority.

Quoting from official dev guide Managing Project -Library Projects:

  • Resource conflicts

    Since the tools merge the resources of a library project with those of a dependent application project, a given resource ID might be defined in both projects. In this case, the tools select the resource from the application, or the library with highest priority, and discard the other resource. As you develop your applications, be aware that common resource IDs are likely to be defined in more than one project and will be merged, with the resource from the application or highest-priority library taking precedence.

Quoting from official dev guide From Eclipse with ADT - Referencing a library project:

If you are adding references to multiple libraries, note that you can set their relative priority (and merge order) by selecting a library and using the Up and Down controls. The tools merge the referenced libraries with your application starting from lowest priority (bottom of the list) to highest (top of the list). If more than one library defines the same resource ID, the tools select the resource from the library with higher priority. The application itself has highest priority and its resources are always used in preference to identical resource IDs defined in libraries.

Quoting from official dev guide From the Command Line - Referencing a Library Project:

If you are adding references to multiple libraries, note that you can set their relative priority (and merge order) by manually editing the project.properties file and adjusting the each reference's .n index as appropriate. For example, assume these references:

 android.library.reference.1=path/to/library_projectA
 android.library.reference.2=path/to/library_projectB
 android.library.reference.3=path/to/library_projectC

You can reorder the references to give highest priority to library_projectC in this way:

 android.library.reference.2=path/to/library_projectA
 android.library.reference.3=path/to/library_projectB
 android.library.reference.1=path/to/library_projectC

I can't find any word that can explain this more clear than official dev guide.

like image 163
yorkw Avatar answered Nov 01 '22 13:11

yorkw