Android Studio:具有两个以上风味维度(风味组)的产品风味组合
Android Studio: product flavor combination with more than two flavor dimensions (flavor groups)
我正在使用 Android Studio(v 2.1,gradle 插件 v 2.1.0)开发一个 Android 应用程序。我的应用程序有多个版本,它们共享很多通用代码,因此我决定使用风味维度和产品风味来在需要的时间和地点自定义代码和资源。只要我只有两个风味维度,这就可以正常工作。例如,我的 app.gradle
是
…
flavorDimensions "fruit", "color"
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
}
…
我的 src
文件夹是
src/
appleRed/
appleYellow/
pearRed/
pearYellow/
每个都有我的代码的自定义版本。再举个例子
src/
appleRed/java/com/example/ExampleFragment.java
appleYellow/java/com/example/ExampleFragment.java
pearRed/java/com/example/ExampleFragment.java
pearYellow/java/com/example/ExampleFragment.java
当然,src/main
中没有ExampleFragment
的实例。
在开发过程中的某个时候,我不得不包含一个 免费 和一个 付费 版本的应用程序。我认为可以通过添加一个名为 version
的新风味维度和两个名为 free
和 paid
:
的产品风味来轻松实现
…
flavorDimensions "fruit", "color”, “version”
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
free {
dimension "version"
}
paid {
dimension “version”
}
}
…
但突然之间,Android Studio 不再检测到由 fruit
和 color
组合生成的自定义代码。因此,appleRed
、appleYellow
、pearRed
和 pearYellow
都不能用于自定义代码,我能够重新获得配置的唯一方法是使用所有组合所有三个风味维度:
src/
appleRedFree/java/com/example/ExampleFragment.java
appleRedPaid/java/com/example/ExampleFragment.java
appleYellowFree/java/com/example/ExampleFragment.java
appleYellowPaid/java/com/example/ExampleFragment.java
pearRedFree/java/com/example/ExampleFragment.java
pearRedPaid/java/com/example/ExampleFragment.java
pearYellowFree/java/com/example/ExampleFragment.java
pearYellowPaid/java/com/example/ExampleFragment.java
这不好,因为 ExampleFragment
在相同的 fruitColor*
组合中重复(appleRedFree
、appleRedPaid
具有相同的 ExampleFragment
)。资源(res
文件夹中的资源)也会出现同样的问题。
我的问题是:
1) 这是 Android Studio 中 gradle 的预期行为吗( 即 ,无法组合产品口味的子集,如下他们的优先级基于他们的维度,当有两个以上的风味维度时)?
2) 考虑到这是预期的行为,是否有另一种方法可以实现我的自定义而无需重复代码或没有带有 if 语句 的单个文件里面(例如,if (BuildConfig.FLAVOR_version == "free") ...
)?
请注意,我说的是拥有可能很复杂的自定义代码,所以我并不是在要求基本的自定义,例如构建配置变量、变体过滤或类似的东西。
您想为某些风格使用相同的额外源目录;
appleRedFree + appleRedPaid --> src/appleRed
pearRedFree + pearRedPaid --> src/pearRed
appleYellowFree + appleYellowPaid --> src/appleYellow
pearYellowFree + pearYellowPaid --> src/pearYellow
您可以根据自己的口味设置 sourceSet:
android {
// Other stuff here
flavorDimensions "fruit", "color”, “version”
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
free {
dimension "version"
}
paid {
dimension “version”
}
}
sourceSets {
appleRedFree {
java.srcDirs = ['src/main/java', 'src/appleRed/java']
}
appleRedPaid {
java.srcDirs = ['src/main/java', 'src/appleRed/java']
}
appleYellowFree {
java.srcDirs = ['src/main/java', 'src/appleYellow/java']
}
appleYellowPaid {
java.srcDirs = ['src/main/java', 'src/appleYellow/java']
}
pearRedFree {
java.srcDirs = ['src/main/java', 'src/pearRed/java']
}
pearRedPaid {
java.srcDirs = ['src/main/java', 'src/pearRed/java']
}
pearYellowFree {
java.srcDirs = ['src/main/java', 'src/pearYellow/java']
}
pearYellowPaid {
java.srcDirs = ['src/main/java', 'src/pearYellow/java']
}
}
// Other stuff here
}
我有一点改进,因为我真的不喜欢 copy/paste src sets :)
所以你可以这样做:
android {
…
applicationVariants.all { variant ->
def flavors = variant.productFlavors
def fruit = flavors[0].name
def color = flavors[1].name
def version = flavors[2].name
def fruitColorSrcSet = fruit + color.capitalize()
def srcSet = fruitColorSrcSet + version.capitalize()
android.sourceSets."$srcSet".java.srcDirs += "src/$fruitColorSrcSet/java"
}
}
我还没有测试过它,但它是基于我当前的实现,另外 variant.buildType.name
使用
附录-设置资源目录使用
android.sourceSets."$srcSet".res.srcDirs = "src/$fruitColorSrcSet/res"
我正在使用 Android Studio(v 2.1,gradle 插件 v 2.1.0)开发一个 Android 应用程序。我的应用程序有多个版本,它们共享很多通用代码,因此我决定使用风味维度和产品风味来在需要的时间和地点自定义代码和资源。只要我只有两个风味维度,这就可以正常工作。例如,我的 app.gradle
是
…
flavorDimensions "fruit", "color"
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
}
…
我的 src
文件夹是
src/
appleRed/
appleYellow/
pearRed/
pearYellow/
每个都有我的代码的自定义版本。再举个例子
src/
appleRed/java/com/example/ExampleFragment.java
appleYellow/java/com/example/ExampleFragment.java
pearRed/java/com/example/ExampleFragment.java
pearYellow/java/com/example/ExampleFragment.java
当然,src/main
中没有ExampleFragment
的实例。
在开发过程中的某个时候,我不得不包含一个 免费 和一个 付费 版本的应用程序。我认为可以通过添加一个名为 version
的新风味维度和两个名为 free
和 paid
:
…
flavorDimensions "fruit", "color”, “version”
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
free {
dimension "version"
}
paid {
dimension “version”
}
}
…
但突然之间,Android Studio 不再检测到由 fruit
和 color
组合生成的自定义代码。因此,appleRed
、appleYellow
、pearRed
和 pearYellow
都不能用于自定义代码,我能够重新获得配置的唯一方法是使用所有组合所有三个风味维度:
src/
appleRedFree/java/com/example/ExampleFragment.java
appleRedPaid/java/com/example/ExampleFragment.java
appleYellowFree/java/com/example/ExampleFragment.java
appleYellowPaid/java/com/example/ExampleFragment.java
pearRedFree/java/com/example/ExampleFragment.java
pearRedPaid/java/com/example/ExampleFragment.java
pearYellowFree/java/com/example/ExampleFragment.java
pearYellowPaid/java/com/example/ExampleFragment.java
这不好,因为 ExampleFragment
在相同的 fruitColor*
组合中重复(appleRedFree
、appleRedPaid
具有相同的 ExampleFragment
)。资源(res
文件夹中的资源)也会出现同样的问题。
我的问题是:
1) 这是 Android Studio 中 gradle 的预期行为吗( 即 ,无法组合产品口味的子集,如下他们的优先级基于他们的维度,当有两个以上的风味维度时)?
2) 考虑到这是预期的行为,是否有另一种方法可以实现我的自定义而无需重复代码或没有带有 if 语句 的单个文件里面(例如,if (BuildConfig.FLAVOR_version == "free") ...
)?
请注意,我说的是拥有可能很复杂的自定义代码,所以我并不是在要求基本的自定义,例如构建配置变量、变体过滤或类似的东西。
您想为某些风格使用相同的额外源目录;
appleRedFree + appleRedPaid --> src/appleRed
pearRedFree + pearRedPaid --> src/pearRed
appleYellowFree + appleYellowPaid --> src/appleYellow
pearYellowFree + pearYellowPaid --> src/pearYellow
您可以根据自己的口味设置 sourceSet:
android {
// Other stuff here
flavorDimensions "fruit", "color”, “version”
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
free {
dimension "version"
}
paid {
dimension “version”
}
}
sourceSets {
appleRedFree {
java.srcDirs = ['src/main/java', 'src/appleRed/java']
}
appleRedPaid {
java.srcDirs = ['src/main/java', 'src/appleRed/java']
}
appleYellowFree {
java.srcDirs = ['src/main/java', 'src/appleYellow/java']
}
appleYellowPaid {
java.srcDirs = ['src/main/java', 'src/appleYellow/java']
}
pearRedFree {
java.srcDirs = ['src/main/java', 'src/pearRed/java']
}
pearRedPaid {
java.srcDirs = ['src/main/java', 'src/pearRed/java']
}
pearYellowFree {
java.srcDirs = ['src/main/java', 'src/pearYellow/java']
}
pearYellowPaid {
java.srcDirs = ['src/main/java', 'src/pearYellow/java']
}
}
// Other stuff here
}
我有一点改进,因为我真的不喜欢 copy/paste src sets :)
所以你可以这样做:
android {
…
applicationVariants.all { variant ->
def flavors = variant.productFlavors
def fruit = flavors[0].name
def color = flavors[1].name
def version = flavors[2].name
def fruitColorSrcSet = fruit + color.capitalize()
def srcSet = fruitColorSrcSet + version.capitalize()
android.sourceSets."$srcSet".java.srcDirs += "src/$fruitColorSrcSet/java"
}
}
我还没有测试过它,但它是基于我当前的实现,另外 variant.buildType.name
使用
附录-设置资源目录使用
android.sourceSets."$srcSet".res.srcDirs = "src/$fruitColorSrcSet/res"