Android资源密钥冲突

我有两个 Android项目,一个主项目(包名com.adip.sampler)和一个添加到main(包名com.samples.projb)的库.在资源中我都有一个具有相同键的整数数组:my_int_values:

在主项目中:

<integer-array name="my_int_values">
    <item>10</item>
    <item>20</item>
    <item>30</item>
    <item>40</item>
    <item>50</item>
    <item>60</item>
    <item>70</item>
    <item>80</item>
</integer-array>

在图书馆:

<integer-array name="my_int_values">
    <item>34</item>
    <item>35</item>
    <item>36</item>
    <item>37</item>
</integer-array>

在活动的主项目中,如果我正在研究这些数组(主项目和库)的值是什么:

protected void showLocalStrings() {
    Log.d("RESSampler","In Main: " + Arrays.toString(getResources().getIntArray(com.adip.sampler.R.array.my_int_values)));
    Log.d("RESSampler","In Libr: " + Arrays.toString(getResources().getIntArray(com.samples.projb.R.array.my_int_values)));
}

然后我在Logcat中看到了这个:

In Main: [10,20,30,40,50,60,70,80]
In Libr: [10,80]

似乎主项目覆盖了库数组中定义的值…如果我正在使用正确的密钥从资源中读取,那么我加倍检查了.直到我看看每个生成的R类.在主项目中,这是我对com.adip.sampler.R.array.my_int_values所拥有的:

在库项目com.samples.projb.R.array.my_int_values中:

Android工具生成了相同的值,所以难怪我得到这种行为.如果我从一个整数数组中更改密钥,我可以摆脱这种行为,但想象你有一些包含大量资源的大型项目,依赖库以及迟早你可能碰到这种问题:拥有具有相同键值的相同类型的资源(我用字符串检查并且字符串数组和上面的行为也出现在那里).所以问题是:

>为什么会出现此问题?或者,如果这不是一个问题,是什么解释了这种行为?
>如何最好地避免它?我猜测尝试在定义键时有某种独特性可以解决问题,但是开发人员往往是懒惰的……

这似乎使用了最新ADT和Eclipse版本(Juno和Indigo)的多种变体.仅在Windows上检查.

public static final class array { public static final int my_int_values=0x7f
<integer-array name="my_int_values">
    <item>10</item>
    <item>20</item>
    <item>30</item>
    <item>40</item>
    <item>50</item>
    <item>60</item>
    <item>70</item>
    <item>80</item>
</integer-array>
<integer-array name="my_int_values"> <item>10</item> <item>20</item> <item>30</item> <item>40</item> <item>50</item> <item>60</item> <item>70</item> <item>80</item> </integer-array>0;
}
public static final class array { public static final int my_int_values = 0x7f
<integer-array name="my_int_values">
    <item>10</item>
    <item>20</item>
    <item>30</item>
    <item>40</item>
    <item>50</item>
    <item>60</item>
    <item>70</item>
    <item>80</item>
</integer-array>
<integer-array name="my_int_values"> <item>10</item> <item>20</item> <item>30</item> <item>40</item> <item>50</item> <item>60</item> <item>70</item> <item>80</item> </integer-array>0;
}

解决方法

Library Projects at Android Developers开始,有许多参考文献,他们明确表示在构建时发生合并,并且具有相同ID的资源会相互覆盖.

对于具有来自库和应用程序的相同ID的资源

In cases where a resource ID is defined in both the application and
the library,the tools ensure that the resource declared in the
application gets priority and that the resource in the library project
is not compiled into the application .apk
. This gives your application
the flexibility to either use or redefine any resource behaviors or
values that are defined in any library.

对于两个库中具有相同ID的资源

… your application can add references to multiple library projects,then
specify the relative priority of the resources in each library. This
lets you build up the resources actually used in your application in a
cumulative manner. When two libraries referenced from an application
define the same resource ID,the tools select the resource from the
library with higher priority and discard the other.

文档中建议的解决方

Use prefixes to avoid resource conflicts

To avoid resource conflicts for common resource IDs,consider using a
prefix or other consistent naming scheme that is unique to the project
(or is unique across all projects).

如何在command line中设置库中的优先级

If you are adding references to multiple libraries,note that you can set their relative priority (and merge order) by manually editing the project.properties file and adjusting the each reference’s .n index as appropriate.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...