[英]Android Studio: product flavor combination with more than two flavor dimensions (flavor groups)
I am developing an Android application using Android Studio (v 2.1, gradle plugin v 2.1.0).我正在使用 Android Studio(v 2.1,gradle 插件 v 2.1.0)开发一个 Android 应用程序。 My application has various versions which share a lot of common code so I decided to use flavor dimensions and product flavors to customize code and resources when and where it is requested.我的应用程序有各种版本,它们共享许多通用代码,因此我决定使用风味维度和产品风味来自定义代码和资源的时间和地点。 This worked fined as long as I only had two flavor dimensions.只要我只有两个风味维度,这种方法就很好用。 As an example, my app.gradle
was例如,我的app.gradle
是
…
flavorDimensions "fruit", "color"
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
}
…
and my src
folder was我的src
文件夹是
src/
appleRed/
appleYellow/
pearRed/
pearYellow/
each one with a custom version of my code.每个都有我的代码的自定义版本。 Again, as an example再举个例子
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
of course, there is no instance of ExampleFragment
in src/main
.当然,在src/main
没有ExampleFragment
实例。
At some point during development, I had to include a free and a paid version of the app.在开发过程中的某个时候,我必须包含该应用程序的免费和付费版本。 I thought that it could be easily achieved by adding a new flavor dimension named version
and two product flavors named free
and paid
:我认为通过添加一个名为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”
}
}
…
but all of a sudden the custom code generated by the combination of fruit
and color
was not detected by Android Studio anymore.但是突然之间,Android Studio 检测不到fruit
和color
组合生成的自定义代码。 So no appleRed
, appleYellow
, pearRed
nor pearYellow
can be used to have custom code and the only way I was able to regain my configuration was to use all the combinations of all the three flavour dimensions:因此,没有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
This is not good because ExampleFragment
is duplicated across the same fruitColor*
combination ( appleRedFree
, appleRedPaid
have the same ExampleFragment
).这不好,因为ExampleFragment
在同一个fruitColor*
组合中重复( appleRedFree
、 appleRedPaid
具有相同的ExampleFragment
)。 Same problem happens for resources (the ones in res
folder).资源( res
文件夹中的res
)也会出现同样的问题。
My questions are:我的问题是:
1) Is this the expected behaviour from gradle in Android Studio ( ie , not being able to combine a subset of product flavors, following their priority based on their dimension, when having more than two flavour dimensions)? 1) 这是 Android Studio 中 gradle 的预期行为(即,当具有两个以上的风味维度时,无法组合产品风味的子集,根据维度的优先级)?
2) Given the fact that this is the expected behaviour, is there another way I can achieve my customisation without duplicated code or without having a single file with an if-statement inside ( eg , if (BuildConfig.FLAVOR_version == "free") ...
) ? 2)鉴于这是预期的行为,是否有另一种方法可以实现我的自定义,而无需重复代码或内部没有带有if 语句的单个文件(例如, if (BuildConfig.FLAVOR_version == "free") ...
)?
Please note that I'm talking about having custom code which could be complex, so I'm not asking for basic customisation like a build config variable, variant filtering, or something like that.请注意,我说的是自定义代码可能很复杂,所以我不是要求基本的自定义,比如构建配置变量、变体过滤或类似的东西。
You want to use same extra source directory for some flavors;您想为某些风格使用相同的额外源目录;
appleRedFree + appleRedPaid --> src/appleRed appleRedFree + appleRedPaid --> src/appleRed
pearRedFree + pearRedPaid --> src/pearRed pearRedFree + pearRedPaid --> src/pearRed
appleYellowFree + appleYellowPaid --> src/appleYellow appleYellowFree + appleYellowPaid --> src/appleYellow
pearYellowFree + pearYellowPaid --> src/pearYellow pearYellowFree + pearYellowPaid --> src/pearYellow
You can set sourceSet for your flavors:您可以为您的口味设置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
}
I have a little enhancement because I really don't like to copy/paste src sets :)我有一点改进,因为我真的不喜欢复制/粘贴 src 集:)
So you can do something like this:所以你可以做这样的事情:
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"
}
}
I haven't tested it but it's based on my current implementation with additionally variant.buildType.name
usage我还没有测试过,但它基于我当前的实现,另外还有variant.buildType.name
用法
Appendix - to set resource directory use附录——设置资源目录使用
android.sourceSets."$srcSet".res.srcDirs = "src/$fruitColorSrcSet/res"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.