原始需求:
分渠道打包,能区分线上线下版本,进而两个版本要共存。
分解:
1、分渠道打包
2、支持按渠道指定 app名称,app图标,app的标识(applicationId)
3、添加环境标记,在打包时指定线上线下环境
4、线下环境特殊配置,线上环境要有默认配置
一、分渠道打包
android {
...
//添加如下标签即可分渠道打包
productFlavors {
online {
}
offline {
}
}
...
}
二、支持按渠道指定 app名称,app图标,app的标识(applicationId)
>1、要修改app名称,app图标,我们可以使用Gradle的manifestPlaceholders实现。首先我们需要在配置文件(AndroidManifest.xml)预先定义好占位符,大致如下:
```
<application
android:name=".MyApplication"
android:allowBackup="false"
android:icon="${app_icon}"
android:label="${app_name}"
android:persistent="true"
android:theme="@style/AppTheme"
tools:replace="name,icon,allowBackup,label">
...
<meta-data
android:name="UMENG_CHANNEL"
android:value="${umeng_channel}"/>
...
</application>
```
然后在需要定制的渠道(比如说offline)中添加如下配置来更改占位符信息。
```
manifestPlaceholders = [app_icon : "@drawable/icon_logo",
app_name : "${appName}-测试",
umeng_channel : "test"]
```
>2、app的标识(applicationId)修改
修改了这个我们就能使两个版本共存(毕竟是两个应用了)。配置如下:
```
applicationIdSuffix ".offLine"//这里是在 applicationId 中添加了一个后缀
```
>3、最后这块整体如下(以offline为例):
```
productFlavors {
online {
}
offline {
applicationIdSuffix ".offLine"//这里是在 applicationId 中添加了一个后缀
manifestPlaceholders = [app_icon : "@drawable/icon_logo",
app_name : "${appName}-测试",
umeng_channel : "test"]
}
}
```
三、添加环境标记,在打包时指定线上线下环境
buildConfigField("boolean", "isOnline", "false")
buildConfigField会在编译时向BuildConfig.java中添加如下字段定义:
// Fields from product flavor: offline
public static final boolean isOnline = false;
接在需要做线上和线下切换的地方使用该变量(BuildConfig.isOnline)控制。
四、线下环境特殊配置,线上环境要有默认配置
>由于分的渠道过多,而且线上渠道的配置又大体相似,如果单个配置显然不合算,所以我们可以试着做个通用(默认)设置。
方法如下(使用gradle的each函数做渠道遍历):
//针对所有的productFlavors在如下遍历
productFlavors.each {
flavor ->
//测试环境不做统一处理
if (flavor.name != "offline") {
flavor.manifestPlaceholders = [app_icon : "@drawable/icon_logo",
app_name : "${appName}",
umeng_channel : name]
flavor.buildConfigField("boolean", "isOnline", "true")
}
}
五、如果打包遇到lint检查问题,可以做如下配置。
//禁用lint检查
lintOptions {
checkReleaseBuilds false
abortOnError false
}
六、整体配置大体如下:
apply plugin: 'com.android.application'
def appName = "应用名称"
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.xxxx.yyy"
minSdkVersion 14
targetSdkVersion 23
}
signingConfigs {
release {
storeFile file("../keystore/release.keystore")
storePassword ""
keyAlias "release_key"
keyPassword ""
}
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
zipAlignEnabled true
}
}
productFlavors {
online {}
baidu {}
"360" {}
yingyongbao {}
xiaomi {}
anzhi {}
offline {
buildConfigField("boolean", "isOnline", "false")
applicationIdSuffix ".offLine"//这里是在 applicationId 中添加了一个后缀
manifestPlaceholders = [app_icon : "@drawable/icon_logo",
app_name : "${appName}-测试",
umeng_channel : "test"]
}
}
// 针对所有的productFlavors在如下遍历
productFlavors.each {
flavor ->
//测试环境不做统一处理
if (flavor.name != "offline") {
flavor.manifestPlaceholders = [app_icon : "@drawable/icon_logo",
app_name : "${appName}",
umeng_channel : name]
flavor.buildConfigField("boolean", "isOnline", "true")
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:support-v4:23.1.1'
compile 'com.google.code.gson:gson:2.2.4'
...
}