缺少Android资源合并中的可选命名空间概念

时间:2015-10-28 20:17:43

标签: android gradle android-gradle

在我的Android应用程序中,我创建了一个与主项目共享一些字符串资源的库。

Main project --------------> main resources (e.g. string)
library project -----------> library resources (e.g. string)

让我们假设:

<string name="app_name">The new app name</string> (in main)
<string name="app_name">The standard app name</string> (in library)

Google表示合并时间有合并,建议在资源级别使用硬编码前缀来阻止合并:

  

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

我认为我有各种必要的行为:

  • 我想要的某些资源图书馆使用主资源覆盖的资源
  • 对于我想要的某些资源继续使用自己的库资源而不使用合并

我认为硬编码前缀是不必要的扩展字符串大小所以我希望谷歌提供一种attr,每个资源文件或每个资源,可选择内部前缀(用作为包名称),以便开发人员可以访问非重写资源。有点像:

<string name="app_name" prefix="yes"></string>

('prefix'attr由我指示编译器将资源保存为例如package_name.app_name以防止与app_name合并)并且在库代码中它将访问字符串

getResources().getPrefixedString(R.id.app_name)

我也知道我可以通过标识符来调用资源,作为一种反思,如

getResources().getIdentifier("res_name", "res_type", "com.library.package");

但是如果我想手动模拟这种行为,这种方法有3个缺点:

  1. 性能降低
  2. 我仍然需要将我的硬编码命名空间添加为所有必需字符串的前缀和
  3. 无法从XML本身调用资源(除非您对前缀进行硬编码)。
  4. 当我想要合并资源时,是否有任何指示编译器的机制?

1 个答案:

答案 0 :(得分:4)

  

当我想要合并资源时,是否有任何指示编译器的机制?

根据您的意见,不是您期望的方式。

  

这就是为什么我希望能够选择性地定义一种命名空间以防止合并库资源

目前,构建工具不支持此功能。保持资源唯一性的前缀取决于开发人员。

当然欢迎您编写自己的工具来帮助自己完成这方面的工作。例如,您可以编写一个Gradle任务来检查相关资源,如果它们缺少前缀并且没有一些XML属性来说&#34;忽略这个&#34;,则无法构建。

  

我也知道我可以通过标识符来调用资源,用一种反射

这不符合您的预期。

您似乎认为库具有独立于应用程序的资源。这是不正确的。库为应用程序提供资源,但所有资源都是一个大池的一部分。因此,您不能使用getIdentifier()并提供一些库名称并获取值。您提供应用程序的应用程序ID,并获取符合您条件的应用程序中的一个资源(假设存在此类资源)。该资源是来自库还是来自应用程序模块并不重要。