6

我有两个 Android 项目,一个主项目(包名com.adip.sampler)和一个添加到主项目(包名)的库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 工具生成了相同的值,所以难怪我会得到这种行为。如果我从一个整数数组中更改键,我可以摆脱这种行为,但想象一下,你有一些具有大量资源、依赖库的大型项目,迟早你可能会遇到这种问题:具有相同键值的相同类型的资源(我已经检查过stringstring-array并且上面的行为也出现在那里)。所以问题是:

  1. 为什么会出现这个问题?或者,如果这不是问题,是什么解释了这种行为?
  2. 如何最好地避免它?我猜想尝试在定义键时具有某种独特性会奏效,但开发人员往往很懒惰......

这使用最新 ADT 和 Eclipse 版本(Juno 和 Indigo)的多个变体出现。仅在 Windows 上检查。

4

2 回答 2

9

从Android Developers 的 Library Projects 中阅读,有许多参考资料清楚地表明合并发生在构建时,并且具有相同 ID 的资源会相互覆盖。

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

如果在应用程序和库中都定义了资源 ID,这些工具会确保应用程序中声明的资源获得优先权,并且库项目中的资源不会编译到应用程序 .apk中。这使您的应用程序可以灵活地使用或重新定义在任何库中定义的任何资源行为或值。

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

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

文档中建议的解决方案

使用前缀避免资源冲突

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

如何从命令行设置库中的优先级

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

于 2013-10-14T07:13:36.810 回答
1

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

理想情况下,您希望能够在 6 个月内忘记这一点,回来查看它并了解该数组的用途/包含什么,而无需深入研究代码来推断该数组的用途。

这个帖子; https://stackoverflow.com/a/7249410/1222199包含一些关于命名约定的不同答案。

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

于 2013-10-14T06:49:26.740 回答