多渠道打包概述
什麼是多渠道包
渠道包就是要在安裝包中添加渠道信息,也就是channel,對應不同的渠道,例如:小米市場、360市場、應用寶市場等
產品在不同的應用市場可能有不同的統計需求,需要爲每個應用市場的Android包設定一個可以區分應用市場的標識,這個爲Android包設定應用市場標識的過程就是多渠道打包。
爲什麼要提供多渠道包
國內存在着有衆多的應用市場,產品在不同的渠道可能有不同的統計需求,爲此Android開發人員需要爲每個應用市場發佈一個安裝包,這裏就引出了Android的多渠道打包。
在安裝包中添加不同的標識,應用在請求網絡的時候攜帶渠道信息,方便後臺做運營統計。
通過配置gradle腳本實現多渠道打包
這種打包方式是使用Android Studio的編譯工具gradle配合使用的,其核心原理就是通過腳本修改AndroidManifest.xml中的mate-date內容,執行N次打包簽名操作實現多渠道打包的需求。然後就可以在java中通過API獲取對應的數據。
多渠道打包實現步驟(友盟爲例)
打包配置
- 按照umeng的要求,manifest文件中需要有(在application下,和activity是並列關係):
<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}">
這段配置,value那裏就是渠道名稱,但是我們在這裏不會去寫渠道名,寫的是一個佔位符,後面gradle編譯的時候會動態的替換掉它。
- 在module(一般也就是app)的build.gradle的android{}中添加配置渠道:
// productFlavors是需要打包的緯度名稱,下方的腳本是將配置文件中的佔位符替換成渠道名稱 productFlavors{ xiaomi { dimension "versionCode" } baidu { dimension "versionCode" } vivo { dimension "versionCode" } _360 { dimension "versionCode" } } // 緯度信息 flavorDimensions("versionCode") productFlavors.all {flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] }
AS3.0以後需要將你原來所有的flavor進行統一管理,用屬性名flavor 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 #85
如果沒有錯誤的情況下我們會在Android studio的BuildVariant看到對應的渠道,如下圖所示: - 獲取渠道
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String channel=getChannel(); Toast.makeText(MainActivity.this, "channel==" + channel, Toast.LENGTH_SHORT).show(); } private String getChannel() { try { PackageManager pm = getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); return appInfo.metaData.getString("UMENG_CHANNEL"); } catch (PackageManager.NameNotFoundException ignored) { } return ""; }
- 配置buildTypes信息以及Apk自定義名稱
buildTypes { debug { // debug 使用release的簽名信息,也可以不配置 // 自動簽名打包時要用到簽名配置 signingConfig signingConfigs.release } release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 自動簽名打包時要用到簽名配置 signingConfig signingConfigs.release // 修改生成的 apk 文件名,輸出 apk 名稱:MyApp_v1.0.0_2017-11-10_debug.apk;MyApp是app的名稱 android.applicationVariants.all { variant -> def suffix if (variant.buildType.name == 'release') { suffix = 'release' } else { suffix = 'debug' } // AS3.0之前這樣重命名 // variant.outputs.each { output -> // def outputFile = output.outputFile // if (outputFile != null && outputFile.name.endsWith('.apk')) { // def fileName = "MyApp_v${defaultConfig.versionName}_${releaseTime()}_${suffix}.apk" // output.outputFile = new File(outputFile.parent, fileName) // } // } // AS3.0之後這樣重命名 variant.outputs.all { outputFileName = "WanAndroid_v${defaultConfig.versionName}_${releaseTime()}_" + "${variant.productFlavors[0].name}_${suffix}.apk" } } } }
releaseTime()是獲取當前時間的方法,配置在build文件的根節點
// 定義打包時間 static def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) }
簽名信息
// 簽名配置 signingConfigs { release { storeFile file('/Users/zly/Downloads/DemoProject/WanAndroid/wanAlias.jks') storePassword '123456' keyAlias = 'wanAndroid' keyPassword '123456' } }
打包
根據簽名方式可分爲兩種打包方式
- 手動簽名打包
- (build -> Generrate Signed Bundle/Apk)選擇已有的簽名文件或者新建
- 選擇打包已經配置過的渠道(選擇release版本)
- 自動簽名打包
- 打開Project Stucture圖形化界面,選擇已有的簽名文件
點擊ok之後就會生成signingConfigs
在Terminal中使用./gradlew assembleRelease 或者 gradle assembleRelease 可進行所有渠道打包。
也可以單獨打包一個渠道,例如 ./gradlew assembleVivoRelease得到Vivo的包
PS:使用gradle命令的前提是配置gradle環境
參考資料: