遇到有一個新需求,需要5個渠道包,每個渠道包的應用圖標不同,啓動頁背景不同,應用名稱不同,網絡地址不同。開始想的就是每次打包替換一下就好了,但是當頻繁更新或渠道包過多的時候你就會崩潰了,所以就想怎麼一次性生成多個渠道包。在網上查找了很多資料,在這裏簡單的進行整理並把自己的一下想發做一下筆記。
一、設置需要替換的數據,這裏有應用名稱、網絡地址、應用圖標、啓動背景。
首先,在app的build.gradle添加如下設置
productFlavors {
app1 {
resValue "string", "app_name", "app1"
resValue "bool", "isrRank", 'true'
buildConfigField "String", "APP_HTML", '"網絡地址1"'
manifestPlaceholders = [ENVIRONMENT: "app1",
icon_logo : "@mipmap/icon_logo", icon_splash : "@drawable/icon_splash"]
}
app2 {
resValue "string", "app_name", "app2"
resValue "bool", "isrRank", 'true'
buildConfigField "String", "APP_HTML", '"網絡地址2"'
manifestPlaceholders = [ENVIRONMENT: "app2",
icon_logo : "@mipmap/icon_logo1", icon_splash : "@drawable/icon_splash1"]
}
}
同時還需要在build.gradle中添加 flavorDimensions "app" 代碼否則會報錯。
resValue "string", "app_name", "app1":參數分別爲數據類型,數據的key,數據的value。注意key不能在項目中string.xml中存在,否則會報錯。
buildConfigField "String", "APP_HTML", '"網絡地址1"':參數與上面相同,此時會在BuildConfig類下生成對應的數據,使用時直接用BuildConfig.APP_HTML即可。
manifestPlaceholders:裏面可以包含多個數據,這裏分別是渠道名、應用圖標、啓動背景
二、代碼中使用上面的數據
1、修改應用圖標
<application
android:allowBackup="true"
android:icon="${icon_logo}"
android:label="@string/app_name"
android:supportsRtl="true"
android:roundIcon="${icon_logo}">
2、修改啓動頁背景
在<application />添加代碼
<!--渠道數據-->
<meta-data
android:name="UMENG_CHANNEL"
android:value="${ENVIRONMENT}" />
<!--啓動頁背景-->
<meta-data
android:name="icon_splash"
android:value="${icon_splash}" />
渠道數據的使用這裏就不說了,這裏直接修改啓動頁背景。
ApplicationInfo info = null;
try {
//獲取數據
info = this.getPackageManager().getApplicationInfo(getPackageName(), PackageManager
.GET_META_DATA);
String welcomePath = info.metaData.getString("icon_splash");
//轉換背景圖片數據類型
Class c = R.drawable.class; //根據圖片位置填寫
Field[] fields = c.getFields();
for (Field field : fields) {
if (field.getName().equals(welcomePath.substring(welcomePath.lastIndexOf("/") + 1,
welcomePath.lastIndexOf(".")))) {
imageView.setBackgroundResource((int) field.get(c.newInstance()));
break;
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
這裏獲取圖片得到的是res/drawable-xxhdpi-v4/icon_splash.png字符串,沒法直接使用,這裏我們把路徑資源轉換成int資源,這裏就用到了Java的反射。
到這裏上面的數據基本就能全部實現了,但渠道包過多的時候包名修改也是個大工程,這裏放一個自動生成應用名+版本號APK文件的設置方法。也是在build.gradle中添加。
android.applicationVariants.all {
variant ->
variant.outputs.all {
outputFileName = "${variant.productFlavors[0].name}_${variant.versionName}.apk"
}
}