安卓系统中的res/values/public.xml文件有什么用处?

64

我在谷歌上搜索过,但没找到相关结果。

我还查看了官方 Android 文档此页面(包含所有可用资源),这些是我能找到的全部。我在这个页面上找到的有关到res/values/目录的相关链接是:

这些页面没有提及res/values/public.xml文件。
这里是我发现的一个示例此类型的文件

代码片段

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <public type="attr" name="commentTextColor" id="0xAA010007" />
    <public type="drawable" name="add_icon_bl" id="0xAA020000" />
    <public type="layout" name="act_date_picker" id="0xAA030001" />
    <public type="anim" name="activity_slide_from_bottom" id="0xAA040000" />
    <public type="xml" name="pref_menu" id="0xAA050000" />
    <public type="raw" name="alert_bell_animation_bl" id="0xAA060000" />
    <public type="array" name="taskRepeat" id="0xAA070000" />
    <public type="color" name="theme_main_color_bl" id="0xAA080000" />
    <public type="string" name="no_internet" id="0xAA0a0001" />
    <public type="id" name="page1" id="0xAA0d0015" />
</resources>

正如您从type属性中可以看到的那样,它包含了您通常放置在res目录下的所有标准资源类型...


为什么有人会想要滥用Android提供的目录并使用单个文件存储所有值?有人能提供更多信息吗?

3个回答

99

res/values/public.xml文件用于给Android资源分配固定的资源ID。

考虑在res/values/strings.xml中的这组字符串资源:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="string1">String 1</string>
    <string name="string3">String 3</string>
</resources>

当应用程序编译时,Android资源打包工具(aapt)可能会为这些资源分配以下资源ID:

public final class R {
    // ...
    public static final class string {
        public static final int string1=0x7f040000;
        public static final int string3=0x7f040001;
    }
}

现在,将字符串资源集更改为:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="string1">String 1</string>
    <string name="string2">String 2</string>
    <string name="string3">String 3</string>
</resources>

你会注意到@string/string3的资源ID已经发生了变化:

public final class R {
    // ...
    public static final class string {
        public static final int string1=0x7f040000;
        public static final int string2=0x7f040001;
        public static final int string3=0x7f040002; // New ID! Was 0x7f040001
    }
}

为了防止这种情况,你可以使用 res/values/public.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <public type="string" name="string3" id="0x7f040001" />
</resources>

这将导致资源ID分配如下:

public final class R {
    // ...
    public static final class string {
        public static final int string1=0x7f040000;
        public static final int string2=0x7f040002;
        public static final int string3=0x7f040001; // Resource ID from public.xml
    }
}

res/values/public.xml 很少被应用程序使用,因为分配给资源的资源ID并不重要。当更改时,整个应用程序都会重新构建,因此 Java 代码中对资源的任何资源ID引用都将被更新。

res/values/public.xml 最重要的用户是 Android 平台本身。针对旧版 Android 构建的应用程序假定某些资源具有特定的资源 ID。例如,Android 资源 @android:style/Theme 必须始终具有资源 ID 0x01030005,以便平台与针对旧版平台构建的应用程序保持向后兼容性。

如果您想了解有关如何分配资源ID的更多详细信息,请参阅此答案:How does the mapping between android resources and resources ID work?


我能否在自己的项目中定义公共资源ID?我尝试过但失败了。@IgorPopov - zhang xuefeng
1
直到2015年,我们可以在自己的项目中使用public.xml来修复资源ID。但是,谷歌在2015年破坏了这个功能(像往常一样)并拒绝修复它。以下是相应问题的链接:link - Stanislav

12

3

这个文件不就是为操作系统代码的作者定义符号名称和系统资源ID之间映射关系而使用的吗?

你可以在SDK中找到它,路径为YOUR_SDK_LOCATION\platforms\android-??\data\res\values。

它的标题是:

此文件定义了平台导出的基本公共资源,始终必须存在

并有以下警告:

任何修改此文件的人请先阅读此重要说明

这个文件定义了资源的二进制兼容性。因此,在此处进行更改时必须非常小心,否则将完全破坏旧应用程序的向后兼容性。

它包含诸如下面的条目:

<public type="attr" name="smallScreens" id="0x01010284" />
<public type="attr" name="normalScreens" id="0x01010285" />
<public type="attr" name="largeScreens" id="0x01010286" />

在IT技术方面,所有系统资源的ID都是固定的,因此任何更改这些条目的人都会破坏他们的代码,以至于它无法在标准设备上运行。


我不知道这个文件是Android SDK的一部分...无论如何,我找到的例子并没有改变现有的值,它只是创建其他自定义的值...所以我认为你发布的限制在这种情况下并不适用。 - Igor Popov
我猜这是为那些想要开发自定义操作系统ROM的人使用的。如果你添加了一个新的系统资源名称/ID,那么你可以编译应用程序代码和ROM代码来利用它。但该应用程序只能在你的自定义ROM手机上运行。 - NickT
不,我是在一个普通的应用程序中发现的,而不是在定制的ROM中。 - Igor Popov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接