原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants

6、 Build Variants(构建变种版本号)

新构建系统的一个目标就是同意为同一个应用创建不同的版本号。

这里有两个基本的使用情景:

1、同一个应用的不同版本号。比如一个免费的版本号和一个收费的专业版本号。

2、同一个应用须要打包成不同的apk以公布Google Play Store。查看http://developer.android.com/google/play/publishing/multiple-apks.html获取很多其它具体信息。

3、综合1和2两种情景。

这个目标就是要让在同一个项目里生成不同的APK成为可能,以代替曾经须要使用一个库项目和两个及两个以上的应用项目分别生成不同APK的做法。

6.1 Product flavors(不同定制的产品)

一个product flavor定义了从项目中构建了一个应用的自己定义版本号。一个单一的项目能够同一时候定义多个不同的flavor来改变应用的输出。

这个新的设计概念是为了解决不同的版本号之间的差异很小的情况。尽管最项目终生成了多个定制的版本号,可是它们本质上都是同一个应用,那么这样的做法可能是比使用库项目更好的实现方式。

Product flavor须要在productFlavors这个DSL容器中声明:

    android {
.... productFlavors {
flavor1 {
...
} flavor2 {
...
}
}
}

这里创建了两个flavor,名为flavor1和flavor2。

注意:flavor的命名不能与已存在的Build Type或者androidTest这个sourceSet有冲突。

6.2 Build Type  + Product Flavor = Build Variant(构建类型+定制产品=构建变种版本号)

正如前面章节所提到的,每个Build Type都会生成一个新的APK。

Product Flavor相同也会做这些事情:项目的输出将会拼接全部可能的Build Type和Product Flavor(假设有Flavor定义存在的话)的组合。

每一种组合(包括Build Type和Product Flavor)就是一个Build Variant(构建变种版本号)。

比如,在上面的Flavor声明样例中与默认的debug和release两个Build Type将会生成4个Build Variant:

* Flavor1 - debug

* Flavor1 - release

* Flavor2 - debug

* Flavor2 - release

项目中假设未定义flavor相同也会有Build Variant,仅仅是使用的是默认的flavor和配置。默认的flavor是没有名字的,所以生成的Build Variant列表看起来就跟Build Type列表一样。

6.3 Product Flavor Configuration(Product Flavor的配置)

每个flavor都是通过闭包来配置的:

    android {
... defaultConfig {
minSdkVersion 8
versionCode 10
} productFlavors {
flavor1 {
packageName "com.example.flavor1"
versionCode 20
} flavor2 {
packageName "com.example.flavor2"
minSdkVersion 14
}
}
}

注意ProductFlavor类型的android.productFlavors.*对象与android.defaultConfig对象的类型是同样的。这意味着它们共享同样的属性。

defaultConfig为全部的flavor提供主要的配置,每个flavor都能够重设这些配置的值。在上面的样例中,终于的配置结果将会是:

* flavor1

        * packageName: com.example.flavor1

        * minSdkVersion: 8

        * versionCode: 20

    * flavor2

        * packageName: com.example.flavor2

        * minSdkVersion: 14

        * versionCode: 10

通常情况下,Build Type的配置会覆盖其他的配置。比如,Build Type的packageNameSuffix会被追加到Product Flavor的packageName上面。

也有一些情况是一些设置能够同一时候在Build Type和Product Flavor中设置。在这样的情况下,依照个别为主的原则决定。

比如,signingConfig就这样的属性的一个样例。

signingConfig同意通过设置android.buildTypes.release.signingConfig来为全部的release包共享同样的SigningConfig。也能够通过设置android.productFlavors.*.signingConfig来为每个release包指定它们自己的SigningConfig。

6.4 Sourcesets and Dependencies(源组件和依赖关系)

与Build Type类似,Product Flavor也会通过它们自己的sourceSet提供代码和资源。

上面的样例将会创建4个sourceSet:

* android.sourceSets.flavor1:位于src/flavor1/

* android.sourceSets.flavor2:位于src/flavor2/

* android.sourceSets.androidTestFlavor1:位于src/androidTestFlavor1/

* android.sourceSets.androidTestFlavor2:位于src/androidTestFlavor2/

这些sourceSet用于与android.sourceSets.main和Build Type的sourceSet来构建APK。

以下的规则用于处理全部使用的sourceSet来构建一个APK:

    * 多个目录中的全部的源码(src/*/java)都会合并起来生成一个输出。

    * 全部的Manifest文件都会合并成一个Manifest文件。类似于Build Type,同意Product Flavor能够拥有不同的的组件和权限声明。

    * 全部使用的资源(Android res和assets)遵循的优先级为Build Type会覆盖Product Flavor,终于覆盖main sourceSet的资源。

    * 每个Build Variant都会依据资源生成自己的R类(或者其他一些源码)。Variant互相之间没有什么是共享的。

终于,类似Build Type,Product Flavor也能够有它们自己的依赖关系。比如,假设使用flavor来生成一个基于广告的应用版本号和一个付费的应用版本号,当中广告版本号可能须要依赖于一个广告SDK,可是还有一个不须要。

    dependencies {
flavor1Compile "..."
}

在这个样例中,src/flavor1/AndroidManifest.xml文件里可能须要声明訪问网络的权限。

每个Variant也会创建额外的sourceSet:

* android.sourceSets.flavor1Debug:位于src/flavor1Debug/

* android.sourceSets.flavor1Release:位于src/flavor1Release/

* android.sourceSets.flavor2Debug:位于src/flavor2Debug/

* android.sourceSets.flavor2Release:位于src/flavor2Release/

这些sourceSet拥有比Build Type的sourceSet更高的优先级,并同意在Variant的层次上做一些定制。

6.5 Building and Tasks(构建和任务)

我们前面提到每个Build Type会创建自己的assemble<name>task,可是Build Variant是Build Type和Product Flavor的组合。

当使用Product Flavor的时候,将会创建很多其它的assemble-type task。各自是:

1、assemble<Variant Name>:同意直接构建一个Variant版本号,比如assembleFlavor1Debug。

2、assemble<Build Type Name>:同意构建指定Build Type的全部APK,比如assembleDebug将会构建Flavor1Debug和Flavor2Debug两个Variant版本号。

3、assemble<Product Flavor Name>:同意构建指定flavor的全部APK,比如assembleFlavor1将会构建Flavor1Debug和Flavor1Release两个Variant版本号。

另外assemble task会构建全部可能组合的Variant版本号。

6.6 Testing(測试)

測试multi-flavors项目很类似于測试简单的项目。

androidTest sourceSet用于定义全部flavor共用的測试,可是每个flavor也能够有它自己特有的測试。

正如前面提到的,每个flavor都会创建自己的測试sourceSet:

* android.sourceSets.androidTestFlavor1:位于src/androidTestFlavor1/

* android.sourceSets.androidTestFlavor2:位于src/androidTestFlavor2/

相同的,它们也能够拥有自己的依赖关系:

    dependencies {
androidTestFlavor1Compile "..."
}

这些測试能够通过main的标志性deviceCheck task或者main的androidTest task(当flavor被使用的时候这个task相当于一个标志性task)来运行。

每个flavor也拥有它们自己的task来这行这些測试:androidTest<VariantName>。比如:

* androidTestFlavor1Debug

* androidTestFlavor2Debug

相同的,每个Variant版本号也会创建相应的測试APK构建task和安装或卸载task:

* assembleFlavor1Test

* installFlavor1Debug

* installFlavor1Test

* uninstallFlavor1Debug

* ...

终于的HTML报告支持依据flavor合并生成。

以下是測试结果和报告文件的路径,第一个是每个flavor版本号的结果,后面的是合并起来的结果:

* build/androidTest-results/flavors/<FlavorName>

* build/androidTest-results/all/

* build/reports/androidTests/flavors<FlavorName>

* build/reports/androidTests/all/

6.7 Multi-flavor variants

在一些情况下,一个应用可能须要基于多个标准来创建多个版本号。比如,Google Play中的multi-apk支持4个不同的过滤器。区分创建的不同APK的每个过滤器要求可以使用多维的Product Flavor。

假如有个游戏须要一个免费版本号和一个付费的版本号,而且须要在multi-apk支持中使用ABI过滤器(译注:ABI,应用二进制接口,长处是不须要修改应用的不论什么代码就行将应用迁移到不论什么支持同样ABI的平台上)。这个游戏应用须要3个ABI和两个特定应用版本号,因此就须要生成6个APK(没有因计算不同Build Types生成的Variant版本号)。

然而,注意到在这个样例中,为三个ABI构建的付费版本号源码都是同样,因此创建6个flavor来实现不是一个好办法。

相反的,使用两个flavor维度,而且自己主动构建全部可能的Variant组合。

这个功能的实现就是使用Flavor Groups。每个Group代表一个维度,而且flavor都被分配到一个指定的Group中。

    android {
... flavorGroups "abi", "version" productFlavors {
freeapp {
flavorGroup "version"
...
} x86 {
flavorGroup "abi"
...
} ...
}
}

andorid.flavorGroups数组依照先后排序定义了可能使用的group。每个Product Flavor都被分配到一个group中。

上面的样例中将Product Flavor分为两组(即两个维度),为别为abi维度[x86,arm,mips]和version维度[freeapp,paidapp],再加上默认的Build Type有[debug,release],这将会组合生成下面的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.flavorGroups中定义的group排序很重要(Variant命名和优先级等)。

每个Variant版本号的配置由几个Product Flavor对象决定:

* android.defaultConfig

* 一个来自abi组中的对象

* 一个来自version组中的对象

flavorGroups中的排序决定了哪一个flavor覆盖哪一个,这对于资源来说很重要,由于一个flavor中的值会替换定义在低优先级的flavor中的值。

flavor groups使用最高的优先级定义,因此在上面样例中的优先级为:

abi > version > defaultConfig

Multi-flavors项目相同拥有额外的sourceSet,类似于Variant的sourceSet,仅仅是少了Build Type:

* android.sourceSets.x86Freeapp:位于src/x86Freeapp/

* android.sourceSets.armPaidapp:位于src/armPaidapp/

* etc...

这同意在flavor-combination的层次上进行定制。它们拥有过比基础的flavor sourceSet更高的优先级,可是优先级低于Build Type的sourceSet。

Android Gradle Plugin指南(五)——Build Variants(构建变种版本号)的更多相关文章

  1. Android Gradle Plugin指南(六)——高级构建定制

    原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Advanced-Build-Customization ...

  2. Android Gradle Plugin指南(三)——依赖关系、android库和多项目配置

    原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Dependencies-Android-Librari ...

  3. Android Gradle Plugin指南(四)——測试

    原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Testing 5.Testing(測试) 构建一个測试 ...

  4. 读书笔记--Android Gradle权威指南(下)

    前言 最近看了一本书<Android Gradle 权威指南>,收获挺多,就想着来记录一些读书笔记,方便后续查阅. 本篇内容是基于上一篇:读书笔记--Android Gradle权威指南( ...

  5. 读书笔记--Android Gradle权威指南(上)

    本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 最近看了一本书<Android Gradle 权威指南>,对于 Gradle 理解又更深了,但不想过段时间就又忘光了,所 ...

  6. Gradle之Android Gradle Plugin 主要 Task 分析(三)

    [Android 修炼手册]Gradle 篇 -- Android Gradle Plugin 主要 Task 分析 预备知识 理解 gradle 的基本开发 了解 gradle task 和 plu ...

  7. Gradle之Android Gradle Plugin 主要流程分析(二)

    [Android 修炼手册]Gradle 篇 -- Android Gradle Plugin 主要流程分析 预备知识 理解 gradle 的基本开发 了解 gradle task 和 plugin ...

  8. The Android Gradle Plugin and Gradle version-compatibility

    http://tools.android.com/tech-docs/new-build-system/version-compatibility Version Compatibility Post ...

  9. Android AS升级3.1 编译报错:The SourceSet 'instrumentTest' is not recognized by the Android Gradle Plugin.

    AndroidStudio升级到3.1后编译报错:The SourceSet ‘instrumentTest’ is not recognized by the Android Gradle Plug ...

随机推荐

  1. java8 - 2

    import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util. ...

  2. Spark(一)Spark简介

    一.官网介绍 1 什么是Spark 官网地址:http://spark.apache.org/ Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎.Spark是UC Berkel ...

  3. ava包(package)的命名规范,java中package命名规则

    Java的包名都有小写单词组成,类名首字母大写:包的路径符合所开发的 系统模块的 定义,比如生产对生产,物资对物资,基础类对基础类.以便看了包名就明白是哪个模块,从而直接到对应包里找相应的实现. 由于 ...

  4. Tomcat --> Cannot create a server using the selected type

    今天在eclipse想把之前的Tomcat 6删掉,重新配置一个,不料没有下一步 Cannot create a server using the selected type 这句话出现在窗口上面,应 ...

  5. 10 Best jQuery and HTML5 WYSIWYG Plugins

    https://www.sitepoint.com/10-best-html-wysiwyg-plugins/

  6. 通过GeneXus如何快速构建微服务架构

    概览 “微服务”是一个非常广泛的话题,在过去几年里,市面上存在着各种不同的定义. 虽然对这种架构方式没有一个非常精确的定义,但仍然有一些概念具有代表性. 微服务有着许多围绕业务能力.自动化部署.终端智 ...

  7. Xshell拖拽上传文件插件

    lrzsz是一款在linux里可代替ftp上传和下载的程序.在linux中支持直接拖拽上传的插件:同时也支持rz和sz进行命令上传和下载. 插件安装 yum -y install lrzsz 上传(r ...

  8. Python 面向对象编程——访问限制

    <无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...

  9. 【WIN10】我的第一個WIN10-UWP應用——古文觀止

    已上架,下載地址:https://www.microsoft.com/store/apps/9nblggh6cc32 特點是:繁體豎排,隱藏/顯示標點符號. 截幾張圖來瞅瞅. 1.主界面 這張圖使用的 ...

  10. [NOI2018]你的名字(SAM+线段树合并)

    考虑l=1,r=n的68分,对S和T建SAM,对T的SAM上的每个节点,计算它能给答案带来多少贡献. T上节点x代表的本质不同的子串数为mx[x]-mx[fa[x]],然后需要去掉所代表子串与S的最长 ...