一般情况下,我们都只有debug和release两种buildType,编译的时候默认debug,正式打包的时候会选择release or/and debug
但由于业务需求,需要为debug和release配置不同的包名和版本号,包名可以通过applicationIdSuffix来实现
首先先看一下applicationSuffix的用法:
android {
defaultConfig {
applicationId "com.example.xxx"
minSdkVersion 21
targetSdkVersion 30
versionCode 100
versionName "1.0.0"
}
buildTypes {
debug {
applicationIdSuffix ".debug"
shrinkResources false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
applicationIdSuffix ".release"
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
按照以上代码,打包或者编译的时候,debug包的包名就是com.example.xxx.debug,对应的,release包的包名就是com.example.xxx.release,但这也也说明了applicationIdSuffix的局限性,applicationIdSuffix只能在默认包名后面追加字符串,至于上面所说的,为不同的包设置不同的版本号也不能实现了。
还有一种更普遍的情形就是需要为不同的市场设置不同的包,比如国内的各大应用市场,一般会打多个包用来发版。
这时候就要用到productFlavors多渠道打包配置了,首先看下基本用法:
android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
flavorDimensions "default"
}
buildTypes {
debug {
shrinkResources false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
productFlavors{
A{
dimension "default"
applicationId "aaa.example.xxx"
versionCode 999
versionName "9.9.9"
buildConfigField 'String', 'PLUGIN_ID', '"someStringA"'
resValue "string", "app_name", "xxx"
manifestPlaceholders = [plugin_id:"someStringA"]
}
B{
dimension "default"
applicationId "bbb.example.xxx"
versionCode 100
versionName "1.0.0"
buildConfigField 'String', 'PLUGIN_ID', '"someStringB"'
resValue "string", "app_name", "xxx"
manifestPlaceholders = [plugin_id:"someStringB"]
}
}
}
按照上面的代码,打包的时候就会有四种选择,分别是ADebug,ARelease,BDebug,BRelease,
A开头的包名就是aaa.example.xxx,版本号是9.9.9,B开头的就是bbb.example.xxx,版本号是1.0.0,编译的时候,可以通过AndroidStudio左下角的BuildVarians来设置,如果没有特殊指定的话,最新的AndroidStudio会按照字母排序,选择最前面那个,比如A和B两个flavor,默认就是ADebug。
buildConfigField 在代码中的使用: BuildConfig.PLUGIN_ID
resValue 在代码中的使用: R.string.app_name
manifestPlaceholders 在代码中的使用: android:value=${plugin_id}
最后说一下dimension这个标识符,Android3.0之后,如果未声明dimension的话会报错:
Error:All flavors must now belong to a named flavor dimension.Learn more at
https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
dimension是维度的意思,这里指的就是flavor的维度,为方便大家理解,我举个简单的例子
有如下应用场景,app打包时要对小米手机和华为手机打不同的包,分别发布到小米应用市场和华为应用市场,那么可以这么设置:
android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
flavorDimensions "brand"
}
buildTypes {
debug {
shrinkResources false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
productFlavors{
huawei{
dimension "brand"
applicationId "aaa.example.xxx"
versionCode 999
versionName "9.9.9"
buildConfigField 'String', 'brand_id', '"huawei"'
}
xiaomi{
dimension "brand"
applicationId "bbb.example.xxx"
versionCode 100
versionName "1.0.0"
buildConfigField 'String', 'brand_id', '"xiaomi"'
}
}
}
这样打包的时候就有四种选择:即huaweiDebug,huaweiRelease,xiaomiDebug,xiaomiRelease,
那么如果这时候,如果分别要对A类别的机型和B类别的机型再做区分(比如A和B的屏幕尺寸、Android版本不同),那么就可以再为flavor增加一个维度:
flavorDimensions "brand","phone"
同时在flavor中声明所在的dimension,代码如下:
android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
flavorDimensions "brand","phone"
}
buildTypes {
debug {
shrinkResources false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
productFlavors{
huawei{
dimension "brand"
applicationId "aaa.example.xxx"
versionCode 999
versionName "9.9.9"
buildConfigField 'String', 'brand_id', '"huawei"'
}
xiaomi{
dimension "brand"
applicationId "bbb.example.xxx"
versionCode 100
versionName "1.0.0"
buildConfigField 'String', 'brand_id', '"xiaomi"'
}
phoneA{
dimension "phone"
buildConfigField 'String', 'phone_type', '"A"'
}
phoneB{
dimension "phone"
buildConfigField 'String', 'phone_type', '"B"'
}
}
}
声明了不同的维度后,再次打包的时候,选项就是这样的了:
xiaomiPhoneADebug,xiaomiPhoneBDebug,xiaomiPhoneARelease,xiaomiPhoneBRelease,
huaweiPhoneADebug,huaweiPhoneBDebug,huaweiPhoneARelease,huaweiPhoneBRelease
一共八个渠道,也就是 xiaomi,huawei,phoneA,phoneB以及debug、release的排列组合,
这就是dmension的作用了,以上只是举例,不代表实际情况,实际项目中这样的需求应该是极少的,一个dimension就够用了。
最后提一下多渠道dimension的覆盖关系,依旧拿上面的代码举例,如果在xiaomi中 ,声明了brand_id这个变量为xiaomi,在phoneA中再次声明brand_id为brandA,代码如下:
xiaomi{
dimension "brand"
applicationId "bbb.example.xxx"
versionCode 100
versionName "1.0.0"
buildConfigField 'String', 'brand_id', '"xiaomi"'
}
phoneA{
dimension "phone"
buildConfigField 'String', 'brand_id', '"brandA"'
buildConfigField 'String', 'phone_type', '"A"'
}
那么最终的结果是以最先声明的维度为准,也就是xiaomi。
以上就是android gradle的productFlavors多渠道打包的使用方法总结。