android资源和资源ID之间的映射是如何工作的?

发布于 2024-11-18 03:55:16 字数 741 浏览 4 评论 0原文

对于 Android 来说,通过 R.id.XXX 就能找到正确的资源,这真是太神奇了。

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

也许它的工作原理如下:

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

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

AAPT 将在 R.java 中生成:

public static final int button1=0x7f05000b;

并且 apk 生成后,@+id/button1 被替换为“0x7f05000b”。

因此,当我们调用:时,

findViewById(R.id.button1);

我们本质上仍然是根据ID进行搜索,尽管ID是像0x7f05000b这样的数字。

谢谢!

ADD

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

比如一张drawable图片是如何通过资源id找到的?或者如何通过资源 ID 找到字符串值?

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

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

Maybe it works like this:

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

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

and AAPT will generate this in the R.java:

public static final int button1=0x7f05000b;

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

Thus, when we call:

findViewById(R.id.button1);

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

Thanks!

ADD

What I really want to know, is how the resource id integer is parsed into the resource content? In other words, how does the Android runtime locate the resource content with resource id as the sole clue?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

七颜 2024-11-25 03:55:16

在构建时,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。

接下来我们看到“drawable”,因此给出 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”获取 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

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.

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.

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).

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

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

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.

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.

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.

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.

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.

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

桃扇骨 2024-11-25 03:55:16

如果您对内部实现(设备端)感兴趣,请查看 Resources.java。有关资源 要了解布局

如何从资源 ID 转换为视图,请查看 LayoutInfater .java

If you are interested in the internal implementation (device side) have a look at loadDrawable() in Resources.java. Refer to hackbod's excellent answer for information about extracting data from the resource table

To know how layouts are translated into View's from resource ID's check out LayoutInfater.java

风和你 2024-11-25 03:55:16

据我了解,aapt 将为每个资源自动生成唯一的 ID,并将它们存储在查找表中。此查找表保留为位于“bin/resources.ap_”中的“resources.arsc”文件(这只是一个 ZIP 文件,因此请随意使用您最喜欢的 ZIP 查看器打开)。查找表也保存为 R.java,如您所知,它允许您引用 Java 中的资源。

如果您想了解有关 ARSC 文件的更多信息,我建议您使用 Google 搜索它,或查看 http 的代码://code.google.com/p/android-apktool/

-担

From what I understand, aapt will auto-generate unique IDs for each of your resources and store them in a look-up table. This look-up table is persisted as the "resources.arsc" file located in "bin/resources.ap_" (this is just a ZIP file, so feel free to open using your favorite ZIP viewer). The look-up table is also persisted as R.java, which as you know allows you to reference your resources in Java.

If you want more information on the ARSC file, I would suggest Googling it, or reviewing the code of http://code.google.com/p/android-apktool/.

-Dan

青柠芒果 2024-11-25 03:55:16

最后一点:在很长一段时间里,我没有使用相对布局,因为许多项目需要引用 xml 文件中更下面的项目,而且我不知道如何引用 @id/foo 尚未定义。

<!-- doesn't work -->
<TextView android:layout_above="@id/foo">above</textview>
<TextView android:id="@+id/foo">below</textview>

然后有一天,我意识到(废话)您可以在引用中定义一个 id;它不必位于带有 id 的元素中:

<!-- works -->
<TextView android:layout_above="@+id/foo">above</textview>
<TextView android:id="@id/foo">below</textview>

One final note: for the longest time, I didn't use relative layouts because many items need to reference items further down in the xml file, and I didn't know how to reference an @id/foo that hadn't been defined yet.

<!-- doesn't work -->
<TextView android:layout_above="@id/foo">above</textview>
<TextView android:id="@+id/foo">below</textview>

Then one day I realized (duh) that you can define an id in the reference; it doesn't have to be in the element that bears the id:

<!-- works -->
<TextView android:layout_above="@+id/foo">above</textview>
<TextView android:id="@id/foo">below</textview>
染墨丶若流云 2024-11-25 03:55:16

神奇之处在于 Eclipse 插件及其在应用程序的“gen”文件夹中自动生成的 R.java 文件。如果您查看此文件,您将看到 R.xx.XXX 中每个 XXX 的静态映射,其中 xx 可以是动画、数组、颜色和所有其他资源类型。

The magic is in the Eclipse plug-in and the R.java file it autogenerates in an app's "gen" folder. If you peek into this file, you'll see static mappings for every XXX in R.xx.XXX where xx can be anim, array, color, and every other resource type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文