20

我有一个 Android 库MyLib,其中包含我的应用程序所需的一切(针对 Android 2.2)。这个库有一个 XML 资源:

drawable/main_background.xml

在我的应用程序MyApp项目中,我引用了MyLib. 在这里,我想覆盖特定资源(即品牌)。所以我添加了一个背景图片MyApp

drawable/main_background.png

Eclipse 不断给我这个错误:

[com.mycom.mylib.myapp] res\drawable\main_background.xml:0: error: Resource entry main_background is already defined.
[com.mycom.mylib.myapp] res\drawable\main_background.png:0: Originally defined here.

如何覆盖库项目中的资源?

4

3 回答 3

11

您不能简单地使用 Android SDK 中具有不同扩展名的文件覆盖资源 ID(它是您要覆盖的资源 ID,而不是实际文件)。但是,您可以通过放入具有相同名称 ( main_background.xml) 的项目 xml 文件并以正确的方式填充它以显示您main_background.png需要提前重命名的新文件 ( ) 来实现这一点。您需要的所有语法都在这里描述:

http://developer.android.com/guide/topics/resources/drawable-resource.html

,在你的情况下,它可能很简单(假设你把它放在你的非图书馆项目中main_background.xml,并且你有你的新 png 作为main_background_new.png):

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/main_background_new" />

使用上述解决方案,您可以@drawable/main_background从您的项目中引用,它应该使用该项目中包含的文件,而不是库文件。

于 2012-08-28T07:52:39.693 回答
4
[com.mycom.mylib.myapp] res\drawable\main_background.xml:0: error: Resource entry main_background is already defined.
[com.mycom.mylib.myapp] res\drawable\main_background.png:0: Originally defined here.

我不相信即使扩展名不同,您也不能拥有相同的文件名。尝试将 png 命名为其他名称。

现在,我没有使用过覆盖,所以这看起来很奇怪,因为您希望这就是您覆盖资产的方式。但是我认为您的库中的两个资产名称相同。而且在您的项目中,拥有同名的资产可能是可以的。但是,我会检查是否可以拥有不同的类型。XML 与 png 不同,如果您从代码访问资产,您可能会遇到类型错误。

让我澄清一下上述观点。我了解库项目可以具有与您的应用程序中的项目具有相同资源 ID 的项目。

然而,上面的错误表明 main_background.png 和 main_background.xml 都在同一个项目([com.mycom.mylib.myapp])中,我认为这是不正确的。

进一步阅读

此页面描述了各种类型的项目,包括库项目http://developer.android.com/tools/projects/index.html

现在我不知道我从哪里得到印象,但再次查看它根本没有说明您可以通过使用相同的资源名称覆盖资源的任何地方。天知道为什么我认为这是一个功能。

所以不,据我所知,同样的规则适用,即使跨图书馆项目,资源也必须唯一命名,否则生成的资源 ID 将发生冲突。(你得到的错误)

解释的是如何管理资源冲突。

资源冲突 由于工具将库项目的资源与依赖应用程序项目的资源合并,因此可能在两个项目中都定义了给定的资源 ID。在这种情况下,工具从应用程序或具有最高优先级的库中选择资源,并丢弃其他资源。在开发应用程序时,请注意公共资源 ID 可能会在多个项目中定义并且将被合并,应用程序或最高优先级库中的资源优先。

系统将使用优先级最高的资源,丢弃其他所有资源。奇怪的是,您会认为不会发生编译错误,因为编译器应该丢弃资源。这让我相信原始海报在同一个项目中具有类似命名的资产,而不是跨 lib 和项目。

我还没有在任何地方读到这实际上是一个预期的功能。有任何链接说别的吗?(评论他们)

于 2012-08-27T20:58:42.643 回答
3

所以这个问题的一个“解决方案”,我不认为这是一个答案:

在相关库中定义一个 XML 文档(我们将其称为 bunny.xml),并让它引用另一个具有相似名称的 xml (bunny_drawn.xml) 并显示实际内容。

然后,在目标项目中,用另一个覆盖 bunny.xml 并使用它来引用具有不同名称的图像 - bunny_image.png

然而,这并不能解决问题,首先因为我们在技术上并没有用 xml 覆盖 png(尽管效果有点接近)。其次,因为覆盖资源的关键特性之一是它们被覆盖,即它们没有被编译到 APK 中:

这些工具确保应用程序中声明的资源获得优先权,并且库项目中的资源不会编译到应用程序 .apk 中

但是 bunny_drawn.xml 仍然会被编译进去!我们可以克服第二点,不仅要在目标 APP 中定义要替换的图像,还要用空白 xml 替换旧的目标 bunny_drawn.xml。(或者,正如 Fenix 指出的那样,在第一种情况下,您可以在 bunny.xml 中包含 bunny_drawn.xml 的内容 - 事实仍然是资源 ID 无法替换......)

所以我的最终结论是,这需要作为开发者工具中的一个错误提交。

于 2012-08-27T20:46:47.863 回答