android资源和资源ID之间的映射是如何工作的? [英] How does the mapping between android resources and resources ID work?

查看:37
本文介绍了android资源和资源ID之间的映射是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Android 仅通过 R.id.XXX 就可以找到合适的资源,这很神奇.

It is magical for Android to locate the proper resource just through the R.id.XXX.

AFAIK,资源被编译成二进制格式,那么这个映射逻辑是如何工作的?

AFAIK, the resources are compiled to binary format, so how does this mapping logic work under the hood?

也许它是这样工作的:

例如,在 layout1.xml 中,我们得到:

For e.g., in the layout1.xml, we got:

<Button android:id="@+id/button1" >

和 AAPT 将在 R.java 中生成它:

and AAPT will generate this in the R.java:

public static final int button1=0x7f05000b;

*.apk 生成后,@+id/button1 将替换为0x7f05000b".

When the *.apk is genrated, the @+id/button1 with be substituded with "0x7f05000b".

因此,当我们调用:

findViewById(R.id.button1);

我们本质上仍然是根据 ID 进行搜索,尽管 ID 是一个类似 0x7f05000b 的数字.

we are essentially still do the search based on the ID, though the ID is a number like 0x7f05000b.

谢谢!

我真正想知道的是,资源id整数是如何解析成资源内容的?换句话说,Android 运行时如何定位以资源 id 为唯一线索的资源内容?

例如,如何找到带有资源id的可绘制图片?或者如何找到带有资源 id 的字符串值?

For example, how is a drawable picture found with a resource id? Or how is a string value is found with a resource id?

推荐答案

在构建时,aapt 工具会收集您定义的所有资源(尽管是单独的文件或文件中的显式定义)并为它们分配资源 ID.

At build time, the aapt tool collects all of the resources you have defined (though separate files or explicit definitions in files) and assigns resource IDs to them.

资源 ID 是一个 32 位数字,格式为:PPTTNNNN.PP 是资源所在的包;TT 是资源的类型;NNNN 是该类型资源的名称.对于应用程序资源,PP 始终为 0x7f.

A resource ID is a 32 bit number of the form: PPTTNNNN. PP is the package the resource is for; TT is the type of the resource; NNNN is the name of the resource in that type. For applications resources, PP is always 0x7f.

TT 和 NNNN 值由 aapt 任意分配——基本上对于每个新类型,分配和使用下一个可用数字(从 1 开始);同样,对于类型中的每个新名称,都会分配并使用下一个可用编号(从 1 开始).

The TT and NNNN values are assigned by aapt arbitrarily -- basically for each new type the next available number is assigned and used (starting with 1); likewise for each new name in a type, the next available number is assigned and used (starting with 1).

所以如果我们让 aapt 按以下顺序处理这些资源文件:

So if we have these resource files handled by aapt in this order:

layout/main.xml
drawable/icon.xml
layout/listitem.xml

我们看到的第一个类型是layout",因此被赋予 TT == 1.该类型下的第一个名称是main",因此被赋予 NNNN == 1.最终的资源 ID 是 0x7f010001.

The first type we see is "layout" so that is given TT == 1. The first name under that type is "main" so that is given NNNN == 1. The final resource ID is 0x7f010001.

接下来我们看到drawable",因此它被赋予 TT == 2.该类型的第一个名称是icon",因此 NNNN == 1.最终的资源 ID 是 0x7f020001.

Next we see "drawable" so that is given TT == 2. The first name for that type is "icon" so that gets NNNN == 1. The final resource ID is 0x7f020001.

最后我们看到另一个布局",它和以前一样具有 TT == 1.这有一个新名称listitem",以便获得下一个值 NNNN == 2.最终资源 ID 为 0x7f010002.

Last we see another "layout" which has TT == 1 as before. This has a new name "listitem" so that gets the next value NNNN == 2. The final resource ID is 0x7f010002.

请注意,默认情况下 aapt 不会尝试在构建之间保持这些标识符相同.每次资源发生变化时,它们都可以获得新的标识符.每次构建它们时,都会使用当前标识符创建一个新的 R.java,以便您的代码获得正确的值.因此,您绝不能将资源标识符保留在可以跨应用的不同构建版本使用的任何位置.

Note that aapt by default makes no attempt to keep these identifiers the same between builds. Each time the resources change, they can all get new identifiers. Each time they are built, a new R.java is created with the current identifiers so your code gets the correct values. Because of this, you must never persist resource identifiers anywhere where they can be used across different builds of your app.

一旦资源被编译并分配了标识符,aapt 就会为您的源代码生成 R.java 文件和一个名为resources.arsc"的二进制文件,该文件包含所有资源名称、标识符和值(对于来来自单独的文件,它们的值是 .apk 中该文件的路径),采用一种可以在运行时在设备上轻松映射和解析的格式.

Once the resources are compiled and identifiers assigned, aapt generates the R.java file for your source code and a binary file called "resources.arsc" that contains all of the resource names, identifiers, and values (for resources that come from separate file, their value is the path to that file in the .apk), in a format that can easily mmapped and parsed on the device at runtime.

您可以使用命令aapt dump resources "获取 apk 中 resources.arsc 文件的摘要.

You can get a summary of the resources.arsc file in an apk with the command "aapt dump resources <path-to-apk>".

二进制资源表的格式记录在资源数据结构的头文件中:

The format of the binary resource table is documented in the header file for the resource data structures here:

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/include/androidfw/ResourceTypes.h

读取设备上资源表的完整实现如下:

The full implementation for reading the resource table on the device is here:

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/ResourceTypes.cpp

这篇关于android资源和资源ID之间的映射是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆