【问题标题】:Cannot override library's xml resource with png resource in application?无法在应用程序中使用 png 资源覆盖库的 xml 资源?
【发布时间】:2012-04-20 19:20:30
【问题描述】:

我有一个 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.

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

【问题讨论】:

  • 你有解决这个问题的办法吗?
  • 对不起。我放弃了这个。我终于制作了一个看起来像我的 xml 的 png。我仍然对我不得不浪费这些 kB 感到不安 :)

标签: android resources library-project


【解决方案1】:

您不能简单地使用 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,它应该使用该项目中包含的文件,而不是库文件。

【讨论】:

  • 嗨,是的,我明白这一点,这与我在答案中发布的示例类似,但 API 声明您可以覆盖资源 ID(它不对扩展名发表评论),所以,老实说,我开始认为这值得一个错误报告。
  • 嗨,我奖励了你,因为你改进了我在帖子中提到的解决方法。但是,我很确定您/应该/能够覆盖 resourceIDs 而不管扩展名如何,所以我想我会在有时间的时候提交错误报告
  • 谢谢,但我认为这永远不可能——当前系统将库和项目中的所有资源视为来自一个项目,并使用相同的资源 ID 创建算法——它首先应该可以在一个项目中包含两个具有相同名称和不同扩展名的文件。
  • 好吧,无论他们检查重复项可能是检查文件名,他们只需要切换它来检查资源ID。
【解决方案2】:
[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 可能是 在多个项目中定义并将与资源合并 优先来自应用程序或最高优先级的库。

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

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

【讨论】:

  • 根据您的报价和赏金评论中的 API 报价,它应该是库项目的“功能”或至少是“属性”。它适用于具有相同名称(包括扩展名)的资源,但这不是 resourceID - 这是您在布局中引用的内容。
  • 另外,即使 OP 在同一个项目中确实有资源,我当然没有,并且遇到了同样的问题。因此,如果您在不同的库中遇到具有相同名称(但扩展名不同)的资源的编译器错误,您是否同意将其报告为开发人员工具错误?
  • 是的,但我也知道资源 id 在项目之间发生冲突的问题是由于它们的链接/设置方式,这是问题所在,我只是找不到 SO 帖子处理它。将其作为一个问题提出。
【解决方案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 无法替换......)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 1970-01-01
    相关资源
    最近更新 更多