Android资源密钥冲突

时间:2013-10-10 21:47:36

标签: android android-resources

我有两个Android项目,一个主项目(包名com.adip.sampler)和一个添加到main(包名com.samples.projb)的库。在这两个资源中,我都有一个integer-array具有相同的键: 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, 20, 30, 40, 50, 60, 70, 80]

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

public static final class array {
    public static final int my_int_values=0x7f060000;
}
在库项目com.samples.projb.R.array.my_int_values

public static final class array {
    public static final int my_int_values = 0x7f060000;
}

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

  1. 为什么出现此问题?或者,如果这不是一个问题,是什么解释了这种行为?
  2. 如何最好地避免它?我猜测尝试在定义键时有某种独特性可以解决问题,但开发人员往往会很懒...
  3. 这似乎使用了最新ADT和Eclipse版本(Juno和Indigo)的多种变体。仅在Windows上检查。

2 个答案:

答案 0 :(得分:8)

Library Projects at Android Developers读取,有许多引用,他们明确表示合并发生在构建时,具有相同ID的资源会相互覆盖。

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

  

在应用程序和服务器中定义资源ID的情况下   库,工具确保在中声明的资源   应用程序获得优先级,并且库项目中的资源   未编译到应用程序.apk 。这给你的应用程序   使用或重新定义任何资源行为的灵活性   在任何库中定义的值。

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

  

...您的应用程序可以添加对多个库项目的引用   指定每个库中资源的相对优先级。这个   允许您在应用程序中构建实际使用的资源   累积方式。 从应用程序引用两个库时   定义相同的资源ID,工具从中选择资源   优先级较高的图书馆,丢弃另一个图书馆。

文档中建议的解决方案

  

使用前缀来避免资源冲突

     

要避免公共资源ID的资源冲突,请考虑使用   前缀或其他一致的命名方案,对项目是唯一的   (或在所有项目中都是独一无二的。)

如何在command line

的库中设置优先级
  

如果要添加对多个库的引用,请注意可以   通过手动编辑来设置它们的相对优先级(和合并顺序)   project.properties文件并将每个引用的.n索引调整为   合适的。

答案 1 :(得分:1)

就个人而言,我会更改资源的名称。如果您阅读有关命名约定的任何内容,它应该是有意义的,“my_int_array”实际上并没有太大帮助,特别是在其他人或项目可能使用的库中。

理想情况下,您希望能够在6个月内忘记这一点,回过头来查看它并知道该数组的用途是什么/包含,而无需通过代码来深入研究通过完成的工作来推断出数组的用途。用它。

这篇文章; https://stackoverflow.com/a/7249410/1222199包含有关命名约定的几个不同答案。

最后,不确定冲突,无法挖掘任何东西。我猜测它与自动生成的方式有关,可能值得将其记录为bug,看看是否得到了开发团队的任何响应。