基础

构建变体(Build Variants)有两部分内容构成 :

buildTypes(构建类型) +  productFlavors(产品风味)

通过 android { } 配置变量进行部署:

android {
    ...
    
    defaultConfig {...}
    
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    productFlavors {
        flavorDimensions "api","flavor"
        flavor1 {
            dimension "flavor"
        }

        flavor2 {
            dimension "flavor"

        }
        
        api1 {
            dimension "api"
        }

        api2 {
            dimension "api"

        }
    }
    
    ...
}

buildTypes

在一般情况下,项目创建时,项目默认创建了两种构建类型 debug 和 release

debug是在项目调试阶段的构建类型,而release则是面向发布。

这两个构建类型方便开发者对两种不同环境进行不同的构建配置。

比如签名信息、so支持类型、debug信息等。

buildTypes DSL

属性/方法

作用

备注

applicationIdSuffix

为计算后的 applicationId 添加该属性指定的后缀

 

consumerProguardFiles

将混淆规则文件添加到构建好的AAR中

 

crunchPngs

是否压缩PNG文件

 

debuggable

是否生成一个可调试的APk文件

 

embedMicroApp

 

 

javaCompileOptions

可以添加Java编译参数

 

jniDebuggable

是否生成一个可调试Native的APK文件

 

manifestPlaceholders

manifest文件占位符配置

 

matchingFallbacks

指定构建匹配失败时降级的构建类型

 

minifyEnabled

是否移除无用的代码

 

multiDexEnabled

Multi-Dex 是否支持

 

multiDexKeepFile

指定在需要主Dex File 存在的内容的声名文件

 

multiDexKeepProguard

指定一个文件,用于在编译时对主Dex classes 的额外混淆规则

 

name

当前构建类型的名字

 

postprocessing

 

 

proguardFiles

指定混淆规则文件

 

pseudoLocalesEnabled

是否生成仿冒资源,通过 resValue 生成

 

renderscriptDebuggable

生成一个用于调试 RenderScript 代码的apk

 

renderscriptOptimLevel

指定 RenderScript的编译优化等级

 

shrinkResources

是否优化未使用的资源

 

signingConfig

签名定义

 

testCoverageEnabled

是否启动覆盖测试

 

useProguard

是否总是启动代码混淆和资源优化

 

versionNameSuffix

添加版本后缀

 

zipAlignEnabled

是否启动zip对其

 

buildConfigField(type, name, value)

添加一个字段到 BuildConfig Class文件中

 

consumerProguardFile(proguardFile)

添加一个需要打包进AAR的混淆文件

 

consumerProguardFiles(proguardFiles)

添加些需要打包进AAR的混淆文件

 

externalNativeBuild(action)

定义native构建参数

 

initWith(that)

复制指定build type的所有属性信息

 

proguardFile(proguardFile)

添加一个混淆定义文件

 

proguardFiles(files)

添加混淆定义文件

 

resValue(type, name, value)

添加一个资源信息

 

setProguardFiles(proguardFileIterable)

设置混淆定义文件

 

仅仅对buildTypes的配置并不能满足我们差异化构建的要求,因此插件中为我们提供了另外的构建配置 productFlavors

productFlavors

productFlavors 和 defaultConfig 同属于 ProductFlavor类。两者的配置内容基本没什么差异,但是在不同变体的构造任务中,对应的变体配置将覆盖默认配置内容。

productFlavors 需要通过 flavorDimensions 创建“模式”名,以用来对 多个flavor进行组织分组。

在上面的 productFlavors {...} 例子中,我们声名了两组模式的productFlavorapiflavor,同时每个模式下,都有两个flavor。

根据构建的组合规则,Android Plugin 会根据这些分组进行组合关系。以上的例子为例。会产生以下几个 productFalvor组合构建任务:

1. api1Flavor1Debug
2. api1Flavor1Release
3. api2Flavor1Debug
4. api2Flavor1Release 
5. api1Flavor2Debug
6. api1Flavor2Release
7. api2Flavor2Debug
8. api2Flavor2Release

Gralde产生的变体数量等同于每个flavor模式的组合数量和构建类型数量的乘积。

falvor每个分组数量 * falvor每个分组数量... * BuildType子项数量

同时产生是名字也是根据 flavorDimensions所声名的模式名顺序进行拼接。

比如例子中在 flavorDimensions "api","flavor"声名后,产生的编译名为api*+flavor*+debug/release的组合关系。

productFlavor DSL

过滤变体

变体是Gradle根据配合内容进行组合增加的,往往会比我们所需求的变体要多,因此为了处理掉不不需要的变体。我们可以通过 variantFilter {}进行过滤。

variantFilter {
        if(it.name.contains("flavor2")){
            it.setIgnore(true)
        }
    }

这样对于变体名中包含 flavor2 的构建变体都将不会出现在 Build Variant 中。

变体源

变体提供了对构建源的隔离,在不同的变体下,可以配置不同的 sourceSet信息。

默认情况下,main/ 的构建源是默认存在的,无论通过任何变体进行构建都将纳入构建范围,因此这里在 main/下存储的都是哥哥变体都共享的资源,而如果需要根据变体信息进行特殊构建的内容,则需要放到对应的变体目录下。

比如对于 api1Flavor1Debug 变体。对于以下几个源都将纳入构建范围:

1. api1/
2. flavor1/
3. debug/
4. api1Flavor1/
5. flavor1Debug/
6. api1Flavor1Debug/

所以如果在这些目录下如果存在同名文件将导致编译冲突。

如果需要考虑其他的构建源,则可以考虑通过 sourceSets {}进行设置,因为 sourceSet 也支持变体设置因此可以通过以下设置,对单独构建变体进行设置:

android {
    sourceSets {
        api2Flavor2 {
            java.srcDirs = [ project.getProjectDir().getAbsolutePath() + '/src/api2Flavor2/temp']
        }
    }
}

这样就在 api2Flavor2 变体构建时,将 '/src/api2Flavor2/temp' 纳入构建范围

注意点

  • 一起编译 java/ 目录中的所有源代码以生成单一的输出。
注:对于给定的构建变体,如果找到两个或两个以上定义同一 Java 类的源集目录,Gradle 就会引发一个构建错误。例如,在构建调试 APK 时,您不能同时定义 src/debug/Utility.java 和 src/main/Utility.java。这是因为 Gradle 会在构建过程中检查这两个目录并引发“duplicate class”错误。如果针对不同的构建类型需要不同版本的 Utility.java,您可以让每个构建类型定义其自己的文件版本,而不将其包含在 main/ 源集中。
  • 所有清单合并为单个清单。将按照上述列表中的相同顺序指定优先级。也就是说,某个构建类型的清单设置会替换某个产品风味的清单设置,依此类推。如需了解更多信息,请阅读合并清单。
  • 同样,values/ 目录中的文件也会合并在一起。如果两个文件同名,例如存在两个 strings.xml 文件,将按照上述列表中的相同顺序指定优先级。也就是说,在构建类型源集中的文件中定义的值将会替换产品风味中同一文件中定义的值,依此类推。
  • res/ 和 asset/ 目录中的资源将打包到一起。如果两个或两个以上的源集中定义有同名资源,将按照上述列表中的相同顺序指定优先级。
  • 最后,在构建 APK 时,Gradle 会为随库模块依赖项包含的资源和清单分配最低的优先级。

变体依赖

正如源设置一样,依赖也支持变体依赖

可以通过添加变体+依赖方式进行设置。

dependencies {
    api2Flavor2Compile 'junit:junit:4.12'
}