一、爲什麼需要多渠道打包?
現在App會上架很多應用商店如:應用寶、小米、華爲等,我們需要統計應用商店註冊量、下載量等就需要在App中寫一個標識然後傳給後臺進行統計這樣的操作就需要用到多渠道打包。
二、爲什麼不用傳統打包方式?
假如現在我們要上架11個應用市場那麼我們就要手動打包11次修改標識11次這樣重複的操作很容易出錯並且也不方便。
三、解決方案
經過我多方調研決定用Gradle進行多渠道打包。
1、在AndroidMainfest中Application標籤下配置meta-data標籤
<meta-data
android:name="CHANNEL"
android:value="${CHANNEL_VALUE}" />
2、在Gradle中Android標籤下配置
/*配置渠道*/
productFlavors {
華爲 {
manifestPlaceholders = [CHANNEL_VALUE: "huawei"]
}
小米 {
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
}
//
應用寶 {
manifestPlaceholders = [CHANNEL_VALUE: "yingyongbao"]
}
'360' {
manifestPlaceholders = [CHANNEL_VALUE: "360"]
}
oppo {
manifestPlaceholders = [CHANNEL_VALUE: "btwj1018oppo"]
}
vivo {
manifestPlaceholders = [CHANNEL_VALUE: "vivo"]
}
魅族 {
manifestPlaceholders = [CHANNEL_VALUE: "meizhu"]
}
三星 {
manifestPlaceholders = [CHANNEL_VALUE: "sanxing"]
}
豌豆莢 {
manifestPlaceholders = [CHANNEL_VALUE: "wandoujia"]
}
}
3、如需配置輸出路徑和apk名稱可在Android標籤下配置
buildTypes {
release {
minifyEnabled true
shrinkResources true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// 自定義輸出配置
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = "app_name_${variant.productFlavors[0].name}_${releaseTime()}.apk"
}
}
}
}
在gradle中配置releaseTime()
//獲取編譯時間
static def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
5、如果配置成功遇到如下錯誤
如果在配置成功後遇到如下錯誤則在defaultConfig
標籤中配置flavorDimensions "versionCode"
6、配置示例
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
>
<application>
<meta-data
android:name="CHANNEL"
android:value="${CHANNEL_VALUE}" />
</application>
</manifest>
Gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.xxxxxxx.xxxxx"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
flavorDimensions "versionCode"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// 自定義輸出配置
applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = "app_name_${variant.productFlavors[0].name}_${releaseTime()}.apk"
}
}
}
debug {
minifyEnabled false
// shrinkResources true
// zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
/*配置渠道*/
productFlavors {
華爲 {
manifestPlaceholders = [CHANNEL_VALUE: "huawei"]
}
小米 {
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
}
'360' {
manifestPlaceholders = [CHANNEL_VALUE: "360"]
}
oppo {
manifestPlaceholders = [CHANNEL_VALUE: "oppo"]
}
vivo {
manifestPlaceholders = [CHANNEL_VALUE: "vivo"]
}
}
}
//獲取編譯時間
static def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
7、獲取標識
public static String getChannel(Context context) {
try {
PackageManager manager = context.getPackageManager();
ApplicationInfo appInfo = manager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
return appInfo.metaData.getString("CHANNEL");
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "";
}
}
8、打包
每次打包的時候直接選擇包就可以了也可以使用gradlew assembleRelease
進行批量打包。