我正在使用Android Studio(v 2.1,gradle plugin v 2.1.0)开发Android应用程序。我的应用程序有各种版本,它们共享许多通用代码,所以我决定使用flavor大小和产品风格来定制代码和资源的时间和地点。只要我只有两个风味尺寸,这就行了罚款。例如,我的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
当然,ExampleFragment
中没有src/main
的实例。
在开发过程中的某个时刻,我必须包含免费和付费版本的应用。我认为可以通过添加名为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-statement (例如,if (BuildConfig.FLAVOR_version == "free") ...
)?
请注意我说的是自定义代码可能很复杂,所以我不是要求基本的自定义,比如构建配置变量,变体过滤或类似的东西。
答案 0 :(得分:11)
您想为某些风格使用相同的额外源目录;
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
}
答案 1 :(得分:2)
我有一些改进,因为我真的不喜欢复制/粘贴src集:)
因此您可以执行以下操作:
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"