使用android studio构建应用的多个版本
使用场景
多渠道分发
多种类型分发,如免费和收费,手机和Pad
目标
公用同一份代码,而不是使用多份代码+1份公用库项目的方式来达到生成多个版本。
使用方法
flavors:一个flavors就是定义一个自定义构建版本。一个项目能包含多个flavors用来生成不同应用。
声明格式:
android {
....
1
2
3
4
5
6
7
8
9
productFlavors {
flavor1 {
...
}
flavor2 {
...
}
}
}
以上示例申明了2个flavors(flavor1和flavor2)。
(注:**flavor名称不得包含已存在Build Type的名称 or with the instrumentTest sourceSet。**)
Build Type + Product Flavor = Build Variant
每个Build Type都会生成一个apk,
每个Flavor也同样会生成一个apk,
他们的组合称之为**Build Variant**。
如此,如果两个flavors(flavor1,flavor2)和两个Build Type(debug,release)组合就会得到4种组合:
flavor1 debug
flavor1 release
flavor2 debug
flavor2 release
在没有声明flavor的情况下,仍然存在flavor,默认配置的flavor将被采用。
android {
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
defaultConfig {
minSdkVersion 8
versionCode 10
}
productFlavors {
flavor1 {
packageName "com.example.flavor1"
versionCode 20
}
flavor2 {
packageName "com.example.flavor2"
minSdkVersion 14
}
}
}
(注:*android.productFlavors.*对象,如这里的flavor1和flavor2的类型为 ___ProductFlavor___,而android.defaultConfig的类型也同样为___ProductFlavor___,这意味 着他们可以共享相同属性,也就是说可以使用同等配置属性,如之上的versionCode*)
defaultConfig在build variant的场景下提供基本配置项,而通过不同flavor来根据自身需求来增加或覆写其中某些配置项。这样的话,之上的示例的配置结果则为:
+ flavor1
- packageName: com.example.flavor1
- minSdkVersion: 8
- versionCode: 20
+ flavor2
- packageName: com.example.flavor2
- minSdkVersion: 14
- versionCode: 10
(*Usually, the Build Type configuration is an overlay over the other configuration. For instance, the Build Type's packageNameSuffix is appended to the Product Flavor's packageName.*)
There are cases where a setting is settable on both the Build Type and the Product Flavor. In this case, it s is on a case by case basis.
For instance, signingConfig is one of these properties.
This enables either having all release packages share the same SigningConfig, by setting android.buildTypes.release.signingConfig, or have each release package use their own SigningConfig by setting each android.productFlavors.*.signingConfig objects separately.
源码与依赖
与Build Type一样,Flavor也有自己资源(code and resources)的放置位置(sourceSets)
如此,之上示例中的放置位置则为:
android.sourceSets.flavor1 : src/flavor1/
android.sourceSets.flavor2 : src/flavor2/
android.sourceSets.instrumentTestFlavor1 : src/instrumentTestFlavor1/
android.sourceSets.instrumentTestFlavor2 : src/instrumentTestFlavor2/
(Those sourceSets are used to build the APK, alongside android.sourceSets.main and the Build Type sourceSet.)
与Build Type一样,Flavor也能有自己依赖项(比如,正式版有对跟踪分析库的依赖,或者是对支付库的依赖)。则可在相应flavor下声明依赖,如:
dependencies {
flavor1Compile "..."
}
(In this particular case, the file src/flavor1/AndroidManifest.xml would probably need to include the internet permission.)
构建
在声明Build Type构建任务时,是通过assemble这个形式的任务名称来的。而Build Variant是Build Type与Flavor的组合,当使用Flavor时,更多的assemble-type被建立起来了,如:
assemble : assembleFlavor1Debug 构建单一的variant,如这里仅针对flavor1的debug版
assemble : assembleDebug 构建单一Build Type下的所有不同Flavors的版本
assemble : assembleFlavor1 构建单一Flavor下所有不同Build Type版本
而assemble任务则构建所有组合。
测试
(*Running the tests can be done through the main deviceCheck anchor task, or the main instrumentTest tasks which acts as an anchor task when flavors are used.*)
参考上面依赖的相关依赖及位置放置,编写相应的测试代码,而任务名称的规则为instrumentTest,如:
instrumentTestFlavor1Debug
instrumentTestFlavor2Debug
执行测试时,构建任务则会对每个variant依次执行:
+ assembleFlavor1Test
+ installFlavor1Debug
+ installFlavor1Test
+ uninstallFlavor1Debug
+ ...
最后的测试结果包裹默认生成位置为:
+ build/instrumentTest-results/flavors/
+ build/instrumentTest-results/all/
+ build/reports/instrumentTests/flavors
+ build/reports/instrumentTests/all/
(Customizing either path, will only change the root folder and still create sub folders per-flavor and aggregated results/reports.)
Multi-flavor variants(待续...)
我遇到的问题
多个Flavor中使用同名的类是否可以?
不行。在所有Build variant中的类唯一。