本文沒有說起到啥新技術,相反的,都是看幾年前的技術,所以,本文不適合安卓開發同窗,對不瞭解的同窗會有必定的幫助;android
所以,請各位大牛勿噴,謝謝~ git
(一臉幽怨)這個事,終究仍是落在jb身上了,事情通過是這樣的:github
每次發版本,安卓都須要上傳N個商店,而不一樣的渠道須要打不一樣的渠道標識,
當APP和後臺交互或者數據上報時,會帶上各自的渠道信息。這樣就能統計
到每一個分發市場的下載數、用戶數等關鍵數據;
複製代碼
這塊呢,原本是讓產品實習生負責,結果呢,過完年後,實習生要回校了,產品老大不肯意作這事,測試只剩下一我的了,順其而然的,這事就落在jb身上; 安全
不幸中的萬幸,以前這塊是一測試妹子負責,當時讓其寫了個文檔,總算有跡可循,一塊兒看看目前我司是如何打渠道包的吧;bash
官網包閉包
先須要一個官網包,能夠理解base包,適用於官網下載或者APP內手動、自動更新這些場景;app
360加固工具
有了官網包,而後就須要打渠道包的工具,我司用的是360加固工具;測試
連接:https://pan.baidu.com/s/1sPRt2vxdXegSBV_wEYH66A
提取碼:nu47
複製代碼
下載解壓,稍後下,還須要兩個文件,簽名文件keystore及密碼、渠道文件;gradle
兩個文件準備好,打開exe、註冊、登陸、添加信息(亂寫便可),就會看到這貨的界面;
點擊應用加固-簽名設置、多渠道設置,分別上傳對應的keystore文件跟渠道文件;
而後點擊添加應用,選擇應用,而後就等着渠道包出來吧;
而後再手動去對應的渠道平臺官網上傳提交審覈就能夠了;
這個流程完,看着也很簡單,沒啥特別的,可是爲啥要說這個事?
由於keystore不能隨便給的啊!!!
既然如此,這種方式存在安全性問題,所以不建議使用,那怎麼辦?
在沒有源碼的事情下,想到的就是反編譯
,而平常用的最多的就是apktool
工具;
流程是這樣的:
這裏說明幾個點:
從新打包apk
apkapktool b newApkDir
複製代碼
從新打包的apk會在newApkDir\dist
下;
簽名
這裏有兩種狀況,沒有簽名跟有簽名,當沒有簽名時,須要先生成keystore
文件;
keytool -genkey -alias jb.keystore -keyalg RSA -validity 20000 -keystore jb.keystore
複製代碼
輸入後須要輸入點內容:
jb.keystore
文件;
有前面文件後,接下來就是簽名了;
jarsigner -verbose -keystore jb.keystore -signedjar jb_signed.apk jb.apk jb.keystore
複製代碼
這裏說明下,jb.apk
就是從新打包後的apk,jb_signed.apk
就是要生成的apk;
keystore
文件,若是別人的APP使用本身的
keystore
,普通功能是沒問題的,可是一旦須要登陸功能,就會報錯,提示簽名跟XX平臺的簽名不一致;
怎麼解決這問題?直接xp,這裏就不展開了;
本身搞的前提是得有源碼,若是連代碼權限都沒有,那就放棄吧;
而下面的例子只會使用demo來簡單演示;
只有一個渠道標識
在AndroidManifest.xml
hardcode對應的曲奧標識;
<meta-data android:value="jbtest" android:name="CHANNEL"/>
複製代碼
多個渠道標識
AndroidManifest.xml
添加渠道信息佔位符;
<meta-data android:name="CHANNEL" android:value="${CHANNEL}" />
複製代碼
在build.grade
設置productFlavors
標籤添加渠道信息:
android{
productFlavors{
"jb"{
manifestPlaceholders = [CHANNEL : "jb"]
}
"jb2"{
manifestPlaceholders = [CHANNEL : "jb2"]
}
}
}
複製代碼
這樣,Gradle
編譯生成多渠道包時,會用不一樣的渠道信息替換AndroidManifest.xml
中的佔位符;
缺點很明顯,每生成一個渠道包,都要從新執行構建流程,國內渠道如此豐富,效率過低了;
這是落魄安卓同窗提供的,github地址點這裏;
雖然github裏面把每一步都講的很清楚,可是由於懶,因此仍是想這裏貼一下gradle
接入的步驟:
1.修改項目根目錄下build.gradle文件,在buildscript下的dependencies中增長:
classpath 'com.meituan.android.walle:plugin:1.1.6'
複製代碼
完整以下:
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.meituan.android.walle:plugin:1.1.6'
}
}
複製代碼
2.修改app工程的build.gradle文件,增長以下信息:
1)頭部增長:
apply plugin: 'walle'
複製代碼
2)須要在buildTypes
中加signingConfig
,不然報這個錯: Error:Plugin requires 'APK Signature Scheme v2 Enabled' for release.
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
複製代碼
這裏說明下signingConfig
,是須要一個keystore
,對這塊有疑問的同窗,請點擊這裏查看;
3)配置wallet信息
walle {
// 指定渠道包的輸出路徑
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定製渠道包的APK的文件名稱
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
channelFile = new File("${project.getProjectDir()}/channel")
}
複製代碼
4)dependencies
新增 compile
:
dependencies {
implementation 'com.meituan.android.walle:library:1.1.6'
}
複製代碼
完整的APP
下的build.grade
內容以下:
apply plugin: 'com.android.application'
apply plugin: 'walle'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.jb.myapplication"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
}
walle {
// 指定渠道包的輸出路徑
apkOutputFolder = new File("${project.buildDir}/outputs/channels");
// 定製渠道包的APK的文件名稱
apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
// 渠道配置文件
channelFile = new File("${project.getProjectDir()}/channel")
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.meituan.android.walle:library:1.1.6'
}
複製代碼
3.添加 channel 渠道文件
直接在APP目錄下添加名爲channel
的文件,內容是須要的渠道信息;
anzhuo
anfen
anbei
PC6
360
yingyongbao
baidu
wandoujia
pp
xiaomi
oppo
lenovo
huawei
複製代碼
4.獲取渠道
在須要獲取渠道信息的地方使用以下代碼獲取渠道信息:
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
複製代碼
4.獲取渠道
生成渠道包的方式是和assemble${variantName}Channels
指令結合, 渠道包的生成目錄默認存放在 build/outputs/apk/
,也能夠經過walle閉包中的apkOutputFolder
參數來指定輸出目錄;
生成渠道包
gradlew clean assembleReleaseChannels
支持 productFlavors
gradlew clean assembleMeituanReleaseChannels
生成單個渠道包
gradlew clean assembleReleaseChannels -PchannelList=anzhuo
生成多個渠道包
gradlew clean assembleReleaseChannels -PchannelList=wandoujia,baidu
Mac的話,就是./gradlew;
複製代碼
原理
原理的話,就是在META-INF
目錄內添加空文件
,能夠不用從新簽名應用,經過爲不一樣渠道的應用添加不一樣的空文件,能夠惟一標識一個渠道;
每打一個渠道包只需複製一個apk,在META-INF中添加一個使用渠道號命名的空文件便可;
這塊的話,網上有大神把腳本開源了,網站自個兒找下吧;
須要的一些環境跟工具,請本身網上了解配置吧;
使用的是jarsigner命令;
jarsigner -certs -verbose -verify xxx.apk
複製代碼
使用aapt命令;
aapt dump badging xxx.apk
複製代碼
反編譯apk,jb用的是apktool
工具,2.4.1
版本;
連接:https://pan.baidu.com/s/1MPWTfXIGzeOUpGZplEkveA
提取碼:6h08
複製代碼
apktool d XX.apk
複製代碼
而後會生成一個目錄,直接找到AndroidManifest.xml
文件,通常經常使用的是友盟,所以直接搜索UMENG_CHANNEL
,若是用的是別的,請自行搜索;
凡事都須要落地,那如何落地?
上面的方案,毫無疑問是選擇第三種,實踐也很簡單,直接在jenkins新增打渠道包的選項便可
本文主要是經過3種方式來說述安卓多渠道包的方式,舊內容,對沒了解過的同窗有必定的幫助,就這樣吧~