今天運營同事給我發了15個應用平臺對應的apk名。我第一反應就是給你個apk自己改名不就完了...于是心中一萬個草泥馬奔騰而過。
轉念一想,這事兒可能不是那么簡單,只怪我圖樣圖森破。于是想到了之前看到過多渠道打包,那么就引出了第一個問題:
一、什么是多渠道
我理解的是:APP發布到不同的應用平臺,監測用戶是從哪個平臺安裝的。
二、為什么要多渠道打包
1. 統計用戶安裝APP來源
知道多渠道的意義就不難理解多渠道打包主要是為了我們統計分析用的。所以,這樣就很清楚了我最初的想法不是不行,而是不好,對今后的產品分析沒有任何幫助。
2.批量修改生成的apk文件名
根據運營給的命名規則,如果是一個個的右鍵-重命名,那15個還好,要真是有1000個,運營同事一定會拿刀找我的...而多渠道打包所有的都自動生成。
3.可更改包名
如果有生成不同包名的需求,通過gradle就可以解決。
4.生成不同應用名稱或圖標
有的時候你會在不同平臺看到XX-小米版,XX-魅族版等等,或者beta版的圖標和正式的不一樣,其實代碼還是那個代碼,無非做點小小的改動,具體實現我們后面會說。
這是我所了解到的,可能還有很多我不知道的用途,歡迎大家在下面留言。
三、如何多渠道打包
多渠道打包網上大概有兩種,一個是通過gradle,另一個是美團介紹的只打一個包,然后解壓替換文件,兩者比較美團的方法要更快,但是今天我們先不做介紹,如果想了解請看《Android多渠道打包飛一般的感覺》。。
1. 在AndroidManifest.xml中添加占位符
一般都是像友盟,騰訊統計分析SDK中使用的方案,網上友盟的較多,我實際用的是騰訊分析所以就拿騰訊的來說(其實都一樣)。
首先,在AndroidManifest.xml
的application
標簽里添加一個meta-data
標簽定義MTA_CHANNEL占位符,騰訊分析SDK會讀取里面的value值傳到后臺,便于我們日后分析。
<meta-data
android:name="MTA_CHANNEL"
android:value="${MTA_CHANNEL_VALUE}" />
2. 修改app
下的build.gradle
文件,在android
閉包中添加productFlavors
屬性配置占位符
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.aimerd.channel"
minSdkVersion 11
targetSdkVersion 21
versionCode 1
versionName "1.0.0"
multiDexEnabled true
}
buildTypes {
release {
// 不顯示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//啟用混淆代碼的功能
minifyEnabled true
//壓縮對齊生成的apk包
zipAlignEnabled true
//指定混淆規則,需要壓縮優化的混淆要把proguard-android.txt換成proguard-android.txt
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//移除無用的資源文件
shrinkResources true
//啟用multidex的支持
multiDexEnabled true
}
}
productFlavors
baidu {
manifestPlaceholders = [MTA_CHANNEL_VALUE: "baidu"]
}
_91 {
manifestPlaceholders = [MTA_CHANNEL_VALUE: "91"]
}
wandoujia {
manifestPlaceholders = [MTA_CHANNEL_VALUE: "wandoujia"]
}
xiaomi {
manifestPlaceholders = [MTA_CHANNEL_VALUE: "xiaomi"]
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (variant.buildType.name.equals('release')) {
//生成apk名字的格式:Channel1.0.0_2016-06-22_baidu.apk
//可自定義自己想要生成的格式
def fileName = "Channel${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.android.support:multidex:1.0.1'
}
如果覺得productFlavors
重復代碼太多,還可以這樣寫:
productFlavors {
baidu {}
_91 {}
wandoujia {}
xiaomi {}
}
//批量處理
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [MTA_CHANNEL_VALUE: name]
}
注意:像91和360這種數字的是不可以的,我試過"91"
雖然可以編譯通過,但打包的時候會報錯
Error:Execution failed for task ':app:transformClassesWithRetrolambdaFor91Release'.
> java.lang.NullPointerException (no error message)
具體原因我不清楚,還請知道原因或者知道解決方法的告訴我一下,謝謝!
3. 打包
-
build->Generate Signed APK...
這個沒什么好說的,很簡單 -
AS的Terminal輸入:
gradle build
可一次性打包所有渠道,如果想打某個渠道的包,先輸入:gradle tasks
找到想要打包的渠道,例如紅框標出的豌豆莢,在終端輸入:gradle assembleWandoujia
,就會單獨打包豌豆莢的包了。
注意:有的輸入命令會提示'gradle'不是內部或外部命令,也不是可運行的程序或批處理文件。說明沒有配置gradle的環境變量,配置成功重啟即可。
4.如何更改包名
剛才提到可以根據不同業務需求,需要更改包名,在productFlavors
中指定不同的applicationId
即可
productFlavors {
baidu {
applicationId="com.aimerd.channel"
manifestPlaceholders = [MTA_CHANNEL_VALUE:"baidu"]
}
}
5.如何生成不同應用名稱或圖標
我們以baidu為例,在app模塊,src目錄下,新建一個與main目錄同級的baidu目錄(這里的名字跟productFlavors
中定義的渠道名要一致):
把
values
下strings.xml
中的"app_name"
改成自己想要的應用名稱。
<resources>
<string name="app_name">哈哈哈-小米版</string>
</resources>
如果需要換圖標,只需更換ic_launcher.png文件即可。