我一直在与gradle和构建变体进行一段时间的努力。
我定义了这些构建类型:
这些口味:
如何为特定构建变体定义唯一资源和资产,即。 FreeDebug?例如,我想要四个不同的应用名称,具体取决于构建变体,每个变体都有不同的图标。
答案 0 :(得分:12)
我一直在努力解决同样的问题。起初我在源代码控制中使用了两个分支,但这是一个让他们保持同步的头痛。 Gradle是一个非常灵活的构建系统,但默认约定并不总是足够。以下是我最终在我的代码库中解决它的方法。
我最终基本上使用了以下目录结构(简化):
+ src
+ main
| + res
| | + values
| | - strings.xml
| + java
| ...
+ debug
| + free
| | + res
| | + values
| | - strings.xml
| + paid
| + res
| + values
| - strings.xml
+ free
| + res
| | + values
| | - strings.xml
| + java
| ...
+ paid
+ res
| + values
| - strings.xml
+ java
...
在主文件夹中,我保留了两种口味常见的一切。在免费文件夹中,我保留了免费版本的所有内容(付费相同)。 flavor文件夹中的文件将覆盖在main文件的顶部。
默认覆盖规则将使用“src”下具有相同名称的文件夹来处理“免费”和“付费”的产品风格。我开始的问题始于构建类型的叠加。
如果我创建了一个与flavor文件夹结构相同的调试文件夹,它将覆盖在当前使用的flavor文件夹之上。这导致两种风格的调试名称相同,但我想要不同的调试名称取决于风味。经过一些研究后,我对我的构建文件进行了以下修改。
...
android {
buildTypes {
debug {
...
}
release {
...
}
}
productFlavors {
free {}
paid {}
}
}
android.applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
...
}
else if (variant.buildType.name == "debug") {
switch (variant.name) {
case "FreeDebug":
variant.mergeResources.doFirst {
android.sourceSets.debug.setRoot("src/debug/free")
}
break;
case "PaidDebug":
variant.mergeResources.doFirst {
android.sourceSets.debug.setRoot("src/debug/paid")
}
break;
}
}
}
...
现在首先覆盖以下文件夹来构建构建变体:
PaidRelease -> /src/main + /src/paid
PaidDebug -> /src/main + /src/paid + /src/debug/paid
FreeRelease -> /src/main + /src/free
FreeDebug -> /src/main + /src/free + /src/debug/free
答案 1 :(得分:11)
根据Gradle Sourcesets and Dependencies guide,您可以添加新文件夹src/freeDebug/res
或src/paidRelease/res
等,以自定义每个构建变体的特定属性。
答案 2 :(得分:1)
创建构建变体时的文件夹结构应为:
app
|
->src
|
->buildvariantname1(as defined in gradle)
|
->java (follow the same structure here, as in main folder)
->res (follow the same structure here, as in main folder)
现在,在选择特定变体时,例如buildVariantname1debug,将选择在此变体下的res文件夹中写入的更改。
应在res-> values文件夹下的string.xml下定义应用名称,以便根据每个构建变体下xml中的值获取应用名称。应用程序图标也是如此。
第二张图片显示,如果您希望每种风格都有不同的代码,drawable和manifest,项目结构如何。请记住,MainActivity将从主文件夹中删除,以便它可以存在于每个构建变体中