6.7 多种定制的版本

有些情况下,人们想基于不同的标准创建同一应用的几个不同的版本。
例如,Google Play 里的 multi-apk 支持4种不同的过滤器。为每一个过滤器创建不同的 APK 就需要用到多维度的 Product Flavor了。

考虑到一个游戏有一个演示版本和一个付费版本,并且在 multi-apk 支持中需要用到 ABI 过滤器。3个 ABI 和两个版本的情况下,就会有6个 APK 生成(没有计算不同的 Build Type的variant 版本)。
然而,对于三个 ABI 来说,他们的付费版本的代码都是一样的,因此只是简单的创建6个 flavor 并不是一个好办法。
相反的,使用两个 flavor 维度,并且自动构建所有可能的 variants。

这个功能通过 Flavor Dimensions 能实现。Flavors 会被指定到特定的维度。

  1. android {
  2. ...
  3. flavorDimensions "abi", "version"
  4. productFlavors {
  5. freeapp {
  6. flavorDimension "version"
  7. ...
  8. }
  9. x86 {
  10. flavorDimension "abi"
  11. ...
  12. }
  13. }
  14. }

android.flavorDimensions 数据定义了可能用到的唯独以及顺序。每一个定义的 Product Flavor 都会被指定一个纬度。

从 Product Flavors [freeapp, paidapp]、[x86, arm, mips]、[debug, release] Build Types 维度,会有以下 build variant 被创建:

  • x86-freeapp-debug
  • x86-freeapp-release
  • arm-freeapp-debug
  • arm-freeapp-release
  • mips-freeapp-debug
  • mips-freeapp-release
  • x86-paidapp-debug
  • x86-paidapp-release
  • arm-paidapp-debug
  • arm-paidapp-release
  • mips-paidapp-debug
  • mips-paidapp-release

通过 android.flavorDimensions 定义的维度的顺序是非常重要的。

每一个 variant 都会被如下几个 Product Flavor 对象配置:

  • android.defaultConfig
  • abi 维度
  • version 维度

维度的顺序决定了哪一个 flavor 会覆盖哪一个 flavor,这对于资源来说非常重要,因为 flavor 会替换掉定义在低优先级 flavor 中的值。

flavor 维度首先使用高优先级的定义。在这里是:

  1. abi > version > defaultConfig

Multi-flavors 工程也有额外的 sourcesets。类似 variant 的 sourcesets,只是没有 build type。

  • android.sourceSets.x86Freeapp ,位置是src/x86Freeapp/
  • android.sourceSets.armPaidapp ,位置是src/armPaidapp/
  • 等等…

这允许你在 flavor-combination 级别上进行定制。他们比普通的 flavor sourcesets 优先级高,但是比 build type sourcesets 优先级低。