在构建时,aapt工具会收集您已定义的所有资源(尽管是单独的文件或文件中的显式定义),并为其分配资源ID。
资源ID是32位数字,格式为:PPTTNNNN。PP是资源所在的包;TT是资源的类型;NNNN是该类型资源的名称。对于应用程序资源,PP始终为0x7f。
TT和NNNN值由aapt任意分配-基本上,对于每种新类型,都会分配并使用下一个可用数字(从1开始);同样,对于类型中的每个新名称,将分配并使用下一个可用编号(从1开始)。
因此,如果我们由aapt按以下顺序处理这些资源文件:
layout/main.xml
drawable/icon.xml
layout/listitem.xml
我们看到的第一种类型是“ layout”,因此被赋予TT ==1。该类型下的名字是“ main”,因此被赋予NNNN ==1。最终资源ID为0x7f010001。
接下来,我们看到“可绘制”,从而得到TT ==2。该类型的名字是“ icon”,因此得到NNNN ==1。最终资源ID为0x7f020001。
最后,我们将看到另一个TT == 1的“布局”。它有一个新名称“ listitem”,以便获得下一个值NNNN ==2。最终资源ID为0x7f010002。
请注意,默认情况下,aapt不会尝试在各个版本之间使这些标识符保持相同。每次资源更改时,它们都可以获取新的标识符。每次构建它们时,都会使用当前的标识符创建一个新的R.java,以便您的代码获得正确的值。因此,您绝不能将资源标识符持久化到可在应用程序的不同内部版本中使用的任何地方。
一旦资源被编译并分配了标识符,aapt就会为您的源代码生成R.java文件,并生成一个名为“ resources.arsc”的二进制文件,其中包含所有资源名称,标识符和值(用于来自单独文件的资源) ,它们的值是.apk中该文件的路径,其格式可以在运行时轻松地在设备上进行映射和解析。
您可以使用命令“ aapt dump resources <path-to-apk>”在apk中获得resources.arsc文件的摘要。
二进制资源表的格式记录在资源数据结构的头文件中,此处:
https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/include/androidfw/ResourceTypes.h
读取设备上资源表的完整实现在这里:
https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/ResourceTypes.cpp