《Gradle for Android》笔记(4):Build Variants,多重构建

cover

  • Build Variant是buildTypes和productFlavor组合的结果。

Build Types 构建类型

  • 构建类型用来定义如何构建应用或者库。
  • debug类型是默认添加的,包含一系列默认属性。如果再添加其他的类型,默认的属性将和debug类型不同。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    android {
    buildTypes {
    staging {
    // applicationId后缀,不影响应用包结构
    applicationIdSuffix ".staging"
    versionNameSuffix "-staging"
    buildConfigField "String", "API_URL", "\"http://staging.example.com/api\""
    }
    }
    }
  • initWith(buildTypes.debug)可以让新的类型继承现有的类型。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    buildTypes {
    staging.initWith(buidTypes.debug)
    staging {
    // 新配置
    }
    }

    buidTypes {
    staging {
    initWith(buildTypes.debug)
    // 新配置
    }
    }
  • 创建新的构建类型之后,Gradle会自动生成对应的源集(source set),默认和新的构建类型同名。但是并不会自动创建目录,所以需要手动创建目录。

  • 构建类型之间的Java类是互斥的,同时只有一个生效,并且不能在main源集中创建同名的类,这样会导致重复定义。
  • 构建类型中的资源(Resources)有特殊的应用方式。
    • DrawableLayout会直接覆盖。
    • values目录下的资源,将会合并(merge)。
    • Android Manifest,也将会合并。
  • 依赖配置中可以通过添加buildTypes前缀来区分不同的构建类型。比如:debugCompile

Product flavors 产品类别

  • buildTypes用于配置同一个App的不同构建;productFlavors用于创建相同构建的不同版本。
  • 例子:分类和免费;OEM定制版;银行、出租车类应用。

    If you are unsure whether you need a new build type, or a new product flavor, you should ask yourself if you want to create a new build of the same app for internal use, or a new APK to publish to Google Play. If you need an entirely new app that needs to be published separately from what you already have, then product flavors are the way to go. Otherwise, you should stick to using build types.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    android { 
    productFlavors {
    red {
    applicationId 'com.gradleforandroid.red'
    versionCode 3
    }
    blue {
    applicationId 'com.gradleforandroid.blue'
    minSdkVersion 14
    versionCode 4
    }
  • productFlavor对应ProductFlavor类,和defaultConfig具有相同的属性。

    ProductFlavorDefaultProductFlavor的子类。(Gradle)

  • productFlavor同样可以有独立的源集,并且可以结合buildTypes创建更加特别的源集。
    • red
    • redDebug、blueRelease
  • 使用flavorDimensions可以增加版本的维度,每个版本可以包含多个不同维度版本的配置。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    android {
    flavorDimensions "color", "price"
    productFlavors {
    red {
    flavorDimension "color"
    }
    blue {
    flavorDimension "color"
    }
    free {
    flavorDimension "price"
    }
    paid {
    flavorDimension "price"
    }
    }
    }

上面代码将redbluefreepaid四个应用版本划分为2个维度:colorprice,这样可创建例如redFreeRelease这样的版本。

  • 一旦声明了flavorDimensions,就必须在每个product flavor中声明各自的维度。
  • flavorDimensions声明的顺序,将影响多个维度结合时属性覆盖的的优先级,从高到低。即color大于price

Build Variants (多重构建)

  • 修改BuildTypes或者ProductFlavors之后,Gradle会自动生成多重构建的配置。
  • 同时也会针对每个构建生成对应的Tasks。
  • Build Variants也可以定制源集。
  • 资源和AndroidManifest融合的优先级。
    • BuildTypes > Flavor > Main > Dependencies
  • Android官方资源
  • 通过过滤器过滤不需要的Build Variants

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // build.gradle文件的最外层
    // 将排除release构建的任意blue版本。
    android.variantFilter { variant ->
    if (variant.buildType.name.equals('release')) {
    variant.getFlavors().each() { flavor ->
    if (flavor.name.equals('blue')) {
    variant.setIgnore(true);
    }
    }
    }
    }
  • 被过滤掉的Build Variants将不会生成Tasks

签名配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
android {
// 签名配置
signingConfigs {
// debug签名是AndroidStudio默认生成的测试签名
staging.initWith(signingConfigs.debug)

release {
// 签名仓库文件
storeFile file("release.keystore")
// 签名仓库密码
storePassword "secretpassword"
// 私钥别名
keyAlias "gradleforandroid"
// 私钥密码
keyPassword "secretpassword"
}
}
}
  • 给BuildVariants配置签名

    1
    2
    3
    4
    5
    6
    7
    8
    android {
    buildTypes {
    release {
    //使用上面的release签名
    signingConfig signingConfigs.release
    }
    }
    }
  • 给不同的版本配置不同的签名

    1
    2
    3
    4
    5
    6
    7
    8
    android {
    buildTypes {
    release {
    productFlavors.red.signingConfig signingConfigs.red
    productFlavors.blue.signingConfig signingConfigs.blue
    }
    }
    }

不在productFlavors直接配置signingConfig的原因是,因为ProductFlavor的配置优先级高于BuildTypes,所以ProductFlavor会覆盖BuildTypes中的签名。
例子:如果给red配置了red签名,那么redDebugredRelease都将有red签名。

其他文章