导入外部类库自动生成各自的R类(选摘)
来源:互联网 发布:淘宝网店装修设计师 编辑:程序博客网 时间:2024/06/05 00:30
Nature of Resources in Application and Library Projects
In previous releases, this inclusion of libraries was source-code based. This meant that
every time the main project was compiled, all the library source files had to be compiled
as well. In the new scheme, the libraries are precompiled and included in the target
application as JAR files.
This compile-time assimilation of libraries poses a couple of unexpected challenges.
Previously, the R.java file for the application project was regenerated when things were
compiled in the target application, including the library source files. This meant that if
you had ten different libraries, R.java was generated once for all of them, and the
generated IDs could be guaranteed to be unique. However, when you precompile, these
IDs belonging to the library projects can get frozen in the compiled JAR files. This will
lead to duplicated IDs.
To fix this, Android has temporarily used a local R.java file for a library to generate the
necessary Java classes, but it doesn’t package the corresponding R.class in the
generated JAR file for that library project. Instead, it relies on the R.java file that is re-created and made available in the application project. As long as the application project
has an R.java file under the same Java package as the library project, the scheme will
work. Figure 16–7 shows how Android has multiple R.java classes/files in the gen
subdirectory of the application project. You see an R.java file for the application and
one R.java file for each of the library projects.
Figure 16–7. Multiple R.java files in the application project
There is one more challenge that needs solving when compiled library JARs are included
in the target application project. When Android compiles the Java classes in the library
project, those Java classes reference the local library R.java constants, because at the
time of compiling the library project, the library project is all that is available. The
application project that uses the library is a future prospect.
If the library’s R.java constants were to be declared static final, then the compiler
would hard-code the constant numbers (such as 0x7778989 ) in the compiled code. This
needs to be stopped if you wish to avoid such duplicate numbers from multiple library
JAR files. The solution Android has adapted is to declare the constants in R.java files as
non-final.
Listing 16–11 shows the R.java file created for our TestLibrary in the library project.
Notice that the IDs are not declared final. They are merely static variables in a Java
class. Typically, these would have been final as well.
Listing 16–11. Non-Final Resource IDs in the Library Project R.java File
These IDs in the library version of the R.java file will help with compiling the Java source
files in the library project. By keeping the IDs as non-final variables, Android prevents the
values for these IDs from getting (hard-coded) into the compiled java class files for the
library.
Now, as you saw in Figure 16–6, these Java JAR files from the library are included into
the application proj ect. Figure 16–7 also showed that the R.java file from the library
(Listing 16–11) is reproduced in the appli cation project. Listing 6-12 shows this re-created library’s R.java file in the application project.
Listing 16–12. Re-created R.java File for the Library’s Resources in the Application Project
All the IDs from the library’s R.java file are re-created in the duplicated R.java file of the
application project. This file also contains IDs from the main application. It is not entirely
clear why there is a need to place app constants in the R.java file belonging to the
library’s Java package.
Also, curiously, the R.java file belonging to the applicatio n’s Java project is identical
except for the Java package name at the top. Li sting 6-13 contains that file just to show
you how identical this file is to the one in Listing 16–12. The only difference, as you can
see, is the Java package name.
Perhaps this answers the previous question that we have pondered: if there is no harm
in mixing the main resources and the library’s resources, why create two files? Just
create one, and copy it with different Java package names at the top.
Listing 16–13. Main Application’s R.java File Containing Combined Resources
In previous releases, this inclusion of libraries was source-code based. This meant that
every time the main project was compiled, all the library source files had to be compiled
as well. In the new scheme, the libraries are precompiled and included in the target
application as JAR files.
This compile-time assimilation of libraries poses a couple of unexpected challenges.
Previously, the R.java file for the application project was regenerated when things were
compiled in the target application, including the library source files. This meant that if
you had ten different libraries, R.java was generated once for all of them, and the
generated IDs could be guaranteed to be unique. However, when you precompile, these
IDs belonging to the library projects can get frozen in the compiled JAR files. This will
lead to duplicated IDs.
To fix this, Android has temporarily used a local R.java file for a library to generate the
necessary Java classes, but it doesn’t package the corresponding R.class in the
generated JAR file for that library project. Instead, it relies on the R.java file that is re-created and made available in the application project. As long as the application project
has an R.java file under the same Java package as the library project, the scheme will
work. Figure 16–7 shows how Android has multiple R.java classes/files in the gen
subdirectory of the application project. You see an R.java file for the application and
one R.java file for each of the library projects.
Figure 16–7. Multiple R.java files in the application project
There is one more challenge that needs solving when compiled library JARs are included
in the target application project. When Android compiles the Java classes in the library
project, those Java classes reference the local library R.java constants, because at the
time of compiling the library project, the library project is all that is available. The
application project that uses the library is a future prospect.
If the library’s R.java constants were to be declared static final, then the compiler
would hard-code the constant numbers (such as 0x7778989 ) in the compiled code. This
needs to be stopped if you wish to avoid such duplicate numbers from multiple library
JAR files. The solution Android has adapted is to declare the constants in R.java files as
non-final.
Listing 16–11 shows the R.java file created for our TestLibrary in the library project.
Notice that the IDs are not declared final. They are merely static variables in a Java
class. Typically, these would have been final as well.
Listing 16–11. Non-Final Resource IDs in the Library Project R.java File
package com.androidbook.library.testlibrary; public final class R { public static final class attr { } public static final class drawable { public static int icon=0x7f020000; public static int robot=0x7f020001; } public static final class id { public static int menuGroup_Main=0x7f050001; public static int menu_clear=0x7f050002; public static int menu_testlib_1=0x7f050003; public static int menu_testlib_2=0x7f050004; public static int text1=0x7f050000; } public static final class layout { public static int lib_main=0x7f030000; } public static final class menu { public static int lib_main_menu=0x7f040000; } }
These IDs in the library version of the R.java file will help with compiling the Java source
files in the library project. By keeping the IDs as non-final variables, Android prevents the
values for these IDs from getting (hard-coded) into the compiled java class files for the
library.
Now, as you saw in Figure 16–6, these Java JAR files from the library are included into
the application proj ect. Figure 16–7 also showed that the R.java file from the library
(Listing 16–11) is reproduced in the appli cation project. Listing 6-12 shows this re-created library’s R.java file in the application project.
Listing 16–12. Re-created R.java File for the Library’s Resources in the Application Project
package com.androidbook.library.testlibrary; public final class R { public static final class attr { } public static final class drawable { public static final int icon=0x7f020000; public static final int robot=0x7f020001; } public static final class id { CHAPTER 16: Exploring Packages 463 public static final int menuGroup_Main=0x7f060001; public static final int menu_clear=0x7f060002; public static final int menu_library_activity=0x7f060005; public static final int menu_testlib_1=0x7f060003; public static final int menu_testlib_2=0x7f060004; public static final int text1=0x7f060000; } public static final class layout { public static final int lib_main=0x7f030000; public static final int main=0x7f030001; } public static final class menu { public static final int lib_main_menu=0x7f050000; public static final int main_menu=0x7f050001; } public static final class string { public static final int app_name=0x7f040001; public static final int hello=0x7f040000; } }
All the IDs from the library’s R.java file are re-created in the duplicated R.java file of the
application project. This file also contains IDs from the main application. It is not entirely
clear why there is a need to place app constants in the R.java file belonging to the
library’s Java package.
Also, curiously, the R.java file belonging to the applicatio n’s Java project is identical
except for the Java package name at the top. Li sting 6-13 contains that file just to show
you how identical this file is to the one in Listing 16–12. The only difference, as you can
see, is the Java package name.
Perhaps this answers the previous question that we have pondered: if there is no harm
in mixing the main resources and the library’s resources, why create two files? Just
create one, and copy it with different Java package names at the top.
Listing 16–13. Main Application’s R.java File Containing Combined Resources
package com.androidbook.library.testlibraryapp; public final class R { public static final class attr { } public static final class drawable { public static final int icon=0x7f020000; public static final int robot=0x7f020001; } public static final class id { public static final int menuGroup_Main=0x7f060001; public static final int menu_clear=0x7f060002; public static final int menu_library_activity=0x7f060005; public static final int menu_testlib_1=0x7f060003; public static final int menu_testlib_2=0x7f060004; public static final int text1=0x7f060000; } public static final class layout { public static final int lib_main=0x7f030000; public static final int main=0x7f030001; } CHAPTER 16: Exploring Packages 464 public static final class menu { public static final int lib_main_menu=0x7f050000; public static final int main_menu=0x7f050001; } public static final class string { public static final int app_name=0x7f040001; public static final int hello=0x7f040000; } }
Implication of Runtime Library Dependency
There is an implication tied to the fact that IDs in the library’s R.java file are not final. It is
common to use a switch statement to respond to menu items based on a menu item ID.
This language construct will fail at compile time when done in the library code if the IDs
are not final. This is because the case statement in a switch clause has to be a real,
constant number, like a #define in C.
So the switch statement in Listing 16–14 will not compile unless the IDs (such as
R.id.menu_item_1) are actual literal numbers or static finals.
Listing 16–14. Sample switch Statement to Demonstrate Non-Final Variables
switch(menuItem.getItemId()) { case R.id.menu_item_1: Statment1; break case 0x7778888: // as an example for R.id.menu_item_2: statement; break; default: statement; }
- 导入外部类库自动生成各自的R类(选摘)
- 每一个导入的类库都生成各自的R类
- 关于android自动生成的R类
- Android 自动生成的R类
- Android 自动生成的R类
- Android工程导入外部jar包时遇到的问题自动生成APK文件
- Android,发现对于外部导入的工程,编译的时候不能够正常生成R.java文件的解决办法
- Eclipse导入ApiDemos后R.java不自动生成的问题
- Eclipse导入ApiDemos后R.java不自动生成的问题
- 导入android项目,无法自动生成R文件的解决方法(Unable to resolve target 'android-7')
- Eclipse导入ApiDemos后R.java不自动生成的问题
- 解决Eclipse导入ApiDemos后R.java不自动生成的问题
- android 导入sample项目时没有自动生成R文件
- java 内部类和外部类互相访问各自的私有成员
- android studio导入外部项目或类库的方法
- 避免导入系统的R类
- 自动生成的R.java有时不可靠
- android 自动生成的R文件说明
- INSTALL_FAILED_MISSING_SHARED_LIBRARY
- Hiberbate新手笔记
- 测试stl
- MySQL常用语句
- C++ 使用模板 实现单例模式
- 导入外部类库自动生成各自的R类(选摘)
- perfmon 的counter 含义描述
- poj 1195
- 秒杀多线程第三篇 原子操作 Interlocked系列函数
- Java基础:三步学会Java Socket编程
- android--Handler
- Struts中常见的错误
- Git服务器在Ubuntu中的搭建
- 图片应用Fotopedia与Expedia公司合作 通过Expedia应用订酒店