由於不可描述(省錢)的原因,公司決定把熱修復方案從付費的sophix遷移到開源(免費)的tinker上來,特此記錄一下多渠道熱修復的踩坑指南
筆者用的是Bugly集成tinker,優點是自帶補丁管理後臺,支持補丁下發/撤回/灰度推送等,接入也是非常簡單了,根據官方指南來就行。Bugly Android熱更新接入文檔
總結完整的接入流程如下:
打基準包安裝並上報聯網(注:填寫唯一的tinkerId)
對基準包的bug修復(可以是Java代碼變更,資源的變更)
修改基準包路徑、修改補丁包tinkerId、mapping文件路徑(如果開啓了混淆需要配置)、resId文件路徑
執行buildTinkerPatchRelease打Release版本補丁包
選擇app/build/outputs/patch目錄下的補丁包並上傳(注:不要選擇tinkerPatch目錄下的補丁包,不然上傳會有問題)
編輯下發補丁規則,點擊立即下發
殺死進程並重啓基準包,請求補丁策略(SDK會自動下載補丁併合成)
再次重啓基準包,檢驗補丁應用結果
查看頁面,查看激活數據的變化
Bugly支持多渠道熱更新,官方推薦用美團的walle進行多渠道打包
爲什麼不推薦配置productFlavors進行多渠道打包呢
因爲1.非常低效,打一個渠道包就要走一下編譯流程,100個渠道包那得多慢。
2.要針對多渠道進行打補丁,如果有100個渠道,就要生成100個補丁,簡直是噩夢
那麼,有沒有版本通過一個補丁就能夠修復所有渠道呢?答案是:有的,但前提是你要保證所有渠道包代碼是一致的。
通過walle或者類似的打包工具,不會改變dex的結構,只是修改APK Signature Block來添加自定義的渠道信息來生成渠道包。
所以walle是一個比較理想的方案。
那麼,要如何獲取渠道信息?
引入walle
dependencies {
compile 'com.meituan.android.walle:library:1.1.3'
}
代碼中使用
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
由於筆者使用了Umeng統計,用Walle注入的渠道信息,Umeng是獲取不到的,要在代碼中把他們建立關聯
//把walle打包注入的渠道信息傳給umeng
MobclickAgent.UMAnalyticsConfig umAnalyticsConfig = new MobclickAgent.UMAnalyticsConfig(context,
UmengConfig.UMENG_APPKEY,
WalleChannelReader.getChannel(getApplication()),
MobclickAgent.EScenarioType.E_UM_NORMAL,
true);
MobclickAgent.startWithConfigure(umAnalyticsConfig);
並且由於項目中需要用到渠道號對應的配置生成推廣鏈接,所以要做一些額外的配置
config.json中
//*****省略的配置*****
"channelInfoList": [
{
"channel": "tuiguang",
"extraInfo": {
"info": "BRbEry"
}
},
]
//*****省略的配置*****
代碼中取出info信息
String info = WalleChannelReader.get(context, "info");//渠道號對應的推廣鏈接後綴
然鵝,用walle注入的簽名信息如果用360加固會失效,參考這裏
本人是用Jay-Goo寫的這個工具。專門修復類似360加固重簽名和批量注入渠道,2秒搞定。支持全平臺
用360加固後的包,經過工具處理,自動生成所有渠道包並注入渠道信息,接下來,用未加固未簽名的基準包,生成補丁,就可以適配360加固後的全渠道啦
注意:
1.需要將應用上傳360加固 網頁-上傳和加固(不簽名),而不是使用360加固助手(因爲PC版會 加固並簽名應用,而且使用的是V1(傳統)簽名))
2.tinker-support.gradle裏面記得打開這個
// 是否啓用加固模式,默認爲false.(tinker-spport 1.0.7起支持)
isProtectedApp = true
3.經過測試,最新版1.9.13還是不兼容360加固,修復後會閃退,詳見這個issue,筆者改回1.9.9測試正常
"tinker":"com.tencent.tinker:tinker-android-lib:1.9.9",//最新版1.9.13有bug,1.9.9使用加固包測試正常
總結下來tinker一個修復流程如下:
- ./gradlew assembleRelease 生成基線包base.apk
- 修復問題後,修改baseApkDir和tinkerId
- 運行buildAllFlavorsTinkerPatchRelease任務,生成patch包
- 把base包上傳到https://jiagu.360.cn/加固,注意不要簽名
- 把加固包命名爲app-release.encrypted.apk,copy到ProtectedApkResignerForWalle根目錄,運行ApkResigner.py
- 最後在channels文件夾下得到已注入渠道信息並簽名後的加固包