文档章节

Android Gradle Plugin指南(五)——Build Variants(构建变种版本)

k
 kim366
发布于 2016/05/13 19:17
字数 2391
阅读 16
收藏 0
点赞 2
评论 0

原文地址: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容器中声明:

[plain] view plain copy
  1. android {  
  2.     ....  
  3.     productFlavors {  
  4.         flavor1 {  
  5.             ...  
  6.         }  
  7.         flavor2 {  
  8.             ...  
  9.         }  
  10.     }  
  11. }  

这里创建了两个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都是通过闭包来配置的:

[plain] view plain copy
  1. android {  
  2.     ...  
  3.     defaultConfig {  
  4.         minSdkVersion 8  
  5.         versionCode 10  
  6.     }  
  7.     productFlavors {  
  8.         flavor1 {  
  9.             packageName "com.example.flavor1"  
  10.             versionCode 20  
  11.         }  
  12.         flavor2 {  
  13.             packageName "com.example.flavor2"  
  14.             minSdkVersion 14  
  15.         }  
  16.     }  
  17. }  

注意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,但是另一个不需要。

[plain] view plain copy
  1. dependencies {  
  2.     flavor1Compile "..."  
  3. }  

在这个例子中,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 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/


同样的,它们也可以拥有自己的依赖关系:

[plain] view plain copy
  1. dependencies {  
  2.     androidTestFlavor1Compile "..."  
  3. }  

这些测试可以通过main的标志性deviceCheck task或者main的androidTest task(当flavor被使用的时候这个task相当于一个标志性task)来执行。


每一个flavor也拥有它们自己的task来进行这些测试:androidTest 。例如:

    * androidTestFlavor1Debug

    * androidTestFlavor2Debug


同样的,每一个Variant版本也会创建对应的测试APK构建task和安装或卸载task:

    * assembleFlavor1Test

    * installFlavor1Debug

    * installFlavor1Test

    * uninstallFlavor1Debug

    * ...


最终的HTML报告支持根据flavor合并生成。

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

    * build/androidTest-results/flavors/

    * build/androidTest-results/all/

    * build/reports/androidTests/flavors/

    * 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中。

[plain] view plain copy
  1. android {  
  2.     ...  
  3.     flavorGroups "abi", "version"  
  4.     productFlavors {  
  5.         freeapp {  
  6.             flavorGroup "version"  
  7.             ...  
  8.         }  
  9.         x86 {  
  10.             flavorGroup "abi"  
  11.             ...  
  12.         }  
  13.         ...  
  14.     }  
  15. }  

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。

本文转载自:http://blog.csdn.net/oyangyujun/article/details/47071151

共有 人打赏支持
k
粉丝 1
博文 129
码字总数 0
作品 0
朝阳

暂无文章

解决dokuwiki创建中文词条文件乱码问题

若直接创建中文词条,打开本地文件夹\dokuwiki\data\pages你会发现,中文字段显示的是URL乱码,需要改一下utf8格式,方法如下:(linux系统亲测有效) 打开 .dokuwiki\conf\local.php 添加一行...

Rhymo-Wu
4分钟前
0
0
设置圆角长条progressbar背景色

1、首先在Drawable下面新建一个xml文件,将这段代码复制进去 <?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-......

王先森oO
4分钟前
0
0
Java语言学习(九):异常处理

异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。常见的三种异常类型有: 检查性异常,如打开一个不存在的文件 运行时异常,如数组越界 错误,如栈溢出 ...

海岸线的曙光
7分钟前
0
0
深入分析golang多值返回以及闭包的实现

一、前言 golang有很多新颖的特性,不知道大家的使用的时候,有没想过,这些特性是如何实现的?当然你可能会说,不了解这些特性好像也不影响自己使用golang,你说的也有道理,但是,多了解底...

万建宁
8分钟前
0
0
img与background-image之间的区别

1.img <img src="图片来源" alt="图片无法显示时显示图片说明性文字" style="设置样式属性" /> img标签虽然不是块状元素,但是可以设置宽高,占位, img设置width后height会自适应匹配,如果...

爱喝水的小熊
10分钟前
0
0
Swift - 添加提示音

func createSound() { //建立的SystemSoundID对象 var soundID:SystemSoundID = 123 //获取声音地址 let path = Bundle.main.path(forResource: "3quan......

west_zll
12分钟前
0
0
为图片写水印的时候中文乱码

缘由:源代码在本地win7 操作系统添加水印正常,但在linux 7.4 上 添加水印乱码(空心方格) 问题的本质是在linux 操作系统中没有对Font 类支持的字体,才会出现乱码 问题截图: 1.系统linux...

qimh
12分钟前
0
0
微信小游戏子域和主域

1、主域只能够设置自身的敏感属性值 2、子域只能够读取自身、朋友、群友的敏感属性值

微信小程序-暗潮
13分钟前
0
0
Django时区详解

引言 相信使用Django的各位开发者在存储时间的时候经常会遇到这样子的错误: RuntimeWarning: DateTimeField received a naive datetime while time zone support is active. 这个错误到底...

bobway
18分钟前
0
0
改造工程步骤

背景: 对于存在有问题的项目(包括 代码不规范 数据库表命名不规范 )需要改造 步骤: 1 新建工程 : 将需要改造的项目拷贝一份 修改项目名称 2 将相应的表结构拷贝到新的数据库中 修改不直...

猿神出窍
24分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部