productFlavors 新版配置
参考资料: gradle-plugin-3-0-0-migration
如果我们在 module 的 build.gradle 指定了某个 product flavor。如下图所示:
productFlavors {
// flavor name
free {}
}
那么必须指定一个 flavor dimension。否则会报错 Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
。
根据文档修改为如下代码:
// freeDimension 为 dimension name
flavorDimensions "freeDimension"
productFlavors {
// flavor name
free {}
}
上面代码配置等同于下面的代码:
// freeDimension 为 dimension name
flavorDimensions "freeDimension"
productFlavors {
// flavor name
free {
dimension "freeDimension"
}
}
原因是我们只指定了一种 flavor dimension — freeDimension。
假如 productFlavors 中包含多个 flavor,也是一样的道理,flavor 中指定的 dimension 默认为 freeDimension。
例如:
// freeDimension 为 dimension name
flavorDimensions "freeDimension"
productFlavors {
// flavor name
free {
dimension "freeDimension"
}
paid {
dimension "freeDimension"
}
}
等同于
// freeDimension 为 dimension name
flavorDimensions "freeDimension"
productFlavors {
// flavor name
free {}
paid {}
}
基本概念
看到这里,我们要明确两个概念,productFlavors 中的 flavor name 和 flavorDimensions 中的 dimension name 是两个东西,不一定要同名。
那么,它们的关系是什么呢?
productFlavors 中的某个 flavor 必须指定某个 dimension,flavorDimensions 下面的 dimension 个数决定了 productFlavors 最多可以被分为几大类。而 productFlavors 下面所有的 flavor 都需要选择“站队“。 (指定 dimension 就是在选择类型)
请往下看例子
例子
假设我们有 app module 和 library module,app module 依赖 library module。
配置一
app module 中的 build.gradle 配置为:
android {
// ... 省略
buildTypes {
release {
minifyEnabled false
}
}
flavorDimensions "freeDimension"
productFlavors {
free {}
paid {}
}
}
dependencies {
implementation project(':library')
}
library module 中的 build.gradle 配置为:
android {
// ... 省略
buildTypes {
release {
minifyEnabled false
}
}
}
最后看下 Build Variants 中的配置:
结果显示:当 app module 中所有 product flavor 都属于同一种 flavor dimension 时,其行为和之前使用 Android Plugin 2.3 系列基本一致。
配置二
app module 中的 build.gradle 配置变为:
flavorDimensions "freeDimension", "paidDimension"
productFlavors {
free {
dimension "freeDimension"
}
paid {
dimension "paidDimension"
}
}
library module 中的 build.gradle 和配置一相同。
最后看下 Build Variants 中的配置:
library module 的配置没有变话,不贴图了。
结果显示:free 和 paid 两个 flavor 由于属于两种 flavor dimension 时,这两个 flavor 会同时编译。请看下图:
如果 app module 种包含三个 flavor 而且分别属于三种 flavor dimension 时,大家猜猜是怎么样?
结果如下:
配置三
app module 中的 build.gradle 配置为:
flavorDimensions "freeDimension", "paidDimension"
productFlavors {
free {
dimension "freeDimension"
}
paid {
dimension "freeDimension"
}
discount {
dimension "paidDimension"
}
}
结果如下:
假如 paidDimension 下面增加一个 flavor 会如何呢?
flavorDimensions "freeDimension", "paidDimension"
productFlavors {
free {
dimension "freeDimension"
}
paid {
dimension "freeDimension"
}
discount {
dimension "paidDimension"
}
limited {
dimension "paidDimension"
}
}
结果如下:
结论
productFlavors 中的 flavor 会根据 flavor dimension 类型分类,然后每个类型下面的 flavor 再分别组合形成新的 product flavor,再与 build type 进行组合,最后构成 Build Variants。
新的 product flavor 个数怎么计算呢?
假设 productFlavors 中所有的 flavor 根据 flavor dimension 分为 N 类(N >= 1),每个类型下面的 flavor 个数为 M1,M2,M3 … M++,新的 product flavor 个数为 F,那么有如下公式:
F = M1 * M2 * M3 * ... * M++
而且,无论 productFlavors 中有几种 flavor dimension 类型,都会在每个类型下选取 flavor 之后同时编译代码。
至此,我们弄清楚了单个 module 中 productFlavors 的配置规律。
代码示例
小提示
我们不可以声明多余的 flavor Dimension,否则会报错。
假如配置如下:
flavorDimensions "freeDimension", "paidDimension", "discountDimension"
productFlavors {
free {
dimension "freeDimension"
}
paid {
dimension "freeDimension"
}
discount {
dimension "discountDimension"
}
}
报错如下:
Error:No flavor is associated with flavor dimension 'paidDimension'.
配置中只使用了 freeDimension 和 discountDimension,所以会报错。