如何使用多个res.srcDirs并使用gradle

时间:2015-07-20 14:05:23

标签: android android-studio gradle build.gradle android-productflavors

我想基于不同的 productFlavors 构建我的应用程序的不同版本,但需要一定程度的灵活性,这是我无法实现的。

这是我的文件夹结构:

+src
  +main
    +java
    +res
  +base
    +java
    +res
  +custom1
    +java
    +res
  +custom2
    +res

公共代码位于 main (服务),基础ui位于 base (活动)。然后,定义新UI的应用程序的自定义版本位于 custom1 (新活动)上。这个运行正常。但我需要另一个版本的应用程序( custom2 ),它使用 base ui,但更改了一些res(图标,字符串或颜色)。

我在build.gradle文件中尝试的是:

android{
    ...
  productFlavors {
    base {
      ...
    }
    custom1 {
      ...
    }
    custom2 {
      ...
    }
  }

  sourceSets{
    custom2{
      java.srcDirs = ['src/base/java']
      res.srcDirs = ['src/custom2/res', 'src/base/res']
    }
  }
}

指定 custom2 将使用 base 的源代码和资源以及 custom2 的资源。

问题是我得到了:

Error: Duplicate resources: <project_path>/src/base/res/values-es/strings.xml:string-en/app_name, <project_path>/src/custom2/res/values-es/strings.xml:string-en/app_name

因为基础 custom2 都定义了app_name,但我的目标是覆盖 base 使用 custom2

我知道如果我没有在app_name中为 custom2 指定任何内容,res.srcDirs将在中覆盖,但随后全部 base 中的资源将无法使用。

方法是否正确?或者我滥用Gradle提供的灵活性?或者有办法做我想做的事情?

提前致谢!

2 个答案:

答案 0 :(得分:6)

你无法以这种方式实现它。

资源合并有一个优先事项:

合并的资源来自3种类型的来源:

  • 与主要sourceSet关联的主要资源,通常位于src / main / res
  • 变体叠加,来自Build Type和Flavor(s)。
  • 图书馆计划依赖项,通过其aar包中的res条目提供资源。

如上所述here

  

如上所述,每个sourceSet都可以定义多个资源文件夹。例如:

android.sourceSets {
   main.res.srcDirs = ['src/main/res', 'src/main/res2']
}
  

在这种情况下,两个资源文件夹都具有相同的优先级。这意味着如果在两个文件夹中声明资源,合并将失败并报告错误

在你的情况下也是如此。您不能以这种方式复制相同的资源。

答案 1 :(得分:1)

我能够通过在src的sibling中添加另一级文件夹(称为shared)来实现这样的功能,然后手动检查+在另一个脚本中组装必要的资源以避免重复。

脚本可在此处找到:https://github.com/smbgood/examples/blob/master/family-resources.gradle

资源将进入这样的文件夹(我们有3个应用'家庭',IG,JB + CB):
/shared/JB/res/values/ids.xml

对于我们现在拥有的每个构建变体,ids.xml“family”中都有一个属性,用于确定要使用的应用程序系列。构建时,脚本会检查在共享中找到的drawable和xml文件,将它们与变体中存在的文件进行比较,然后删除重叠的项目,最后将所需的项目写入/ assemble /文件夹。