android开发中资源文件和资源ID是如何映射的

来源:互联网 发布:电商美工月度自我评价 编辑:程序博客网 时间:2024/06/05 12:22
问题描述:


做Android应用开发的时候,我们知道可以通过 R.id.xxx 来非常方便的访问应用程序的资源。


但是任何资源最终要编译成二进制格式的,那么在这种机制下,系统是如何工作的?


例如,在layout1.xml里面,我们这样写:


1
<Button android:id="@+id/button1" >
然后AAPT 会生成R.java文件:


1
public static final int button1=0x7f05000b;
接下来在生成*.apk的时候,像 @+id/button1   这样的ID会用”0x7f05000b”这样的数字代替


所以,我们在调用


1
findViewById(R.id.button1);
的时候,实际上调用的是像”0x7f05000b”这样的资源ID。那么这中间到底发生了什么呢?例如系统是如何把一个图片和数字ID对应起来的呢?


回答:




在编译的时候,AAPT会扫描你所定义的所有资源(在不同文件中定义的以及单独的资源文件),然后给它们指定不同的资源ID。


资源ID 是一个32bit的数字,格式是PPTTNNNN , PP代表资源所属的包(package) ,TT代表资源的类型(type),NNNN代表这个类型下面的资源的名称。 对于应用程序的资源来说,PP的取值是0×77。


TT 和NNNN 的取值是由AAPT工具随意指定的–基本上每一种新的资源类型的数字都是从上一个数字累加的(从1开始);而每一个新的资源条目也是从数字1开始向上累加的。


所以如果我们的这几个资源文件按照下面的顺序排列,AAPT会依次处理:


1
layout/main.xml
2


3
drawable/icon.xml
4


5
layout/listitem.xml
按照顺序,第一个资源的类型是”layout” 所以指定TT==1, 这个类型下面的第一个资源是”main” ,所以指定NNNN==1 ,最后这个资源就是0x7f010001。


第二个资源类型是”drawable”,所以指定TT==2,这个类型下的”icon” 指定NNNN ==1,所以最终的资源ID 是 0x7f020001。


第三个资源类型是”layout”,而这个资源类型在前面已经有定义了,所以TT仍然是1,但是”listitem”这个名字是新出现的,所以指定NNNN==2,因此最终的资源ID 就是 0x7f010002。


注意的是,AAPT在每一次编译的时候不会去保存上一次生成的资源ID标示,每当/res目录发生变化的时候,AAPT可能会去重新给资源指定ID号,然后重新生成一个R.java文件。因此,在做开发的时候,你不应该在程序中将资源ID持久化保存到文件或者数据库。而资源ID在每一次编译后都有可能变化。


一旦资源被编译成二进制文件的时候,AAPT会生成R.java 文件和“resources.arsc”文件,“R.java”用于代码的编译,而”resources.arsc”则包含了全部的资源名称、资源ID和资源的内容(对于单独文件类型的资源,这个内容代表的是这个文件在其.apk 文件中的路径信息)。这样就把运行环境中的资源ID 和具体的资源对应起来了。


在调试的时候,你可以使用“ aapt dump resources <apk的路径>”来看到对resources.arsc文件的详细描述信息。


关于二进制资源表的详细定义在 resources数据结构的定义头文件里面:


http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=include/utils/ResourceTypes.h


关于设备上使用的二进制资源的具体实现在这里:


http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=libs/utils/ResourceTypes.cpp

原文链接:http://tweetyf.org/2013/02/mapping_between_res_resid_android.html
0 0
原创粉丝点击