Bugly熱更新采用Tinker開(kāi)源方案,官方文檔如下:
Bugly Android熱更新使用指南
Bugly Android熱更新詳解
接入熱更新
我們的章魚(yú)App之前就已經(jīng)接入了Bugly,所以添加熱更新支持,只需在gradle文件中進(jìn)行如下更改即可。
/// 注釋掉之前的bugly
//"bugly": 'com.tencent.bugly:crashreport:latest.release', //日志統(tǒng)計(jì)
// 添加支持熱更新的 bugly
"bugly": 'com.tencent.bugly:crashreport_upgrade:latest.release', //日志統(tǒng)計(jì)(1.3.4之前含Tinker熱更新,現(xiàn)已剝離)
"tinker": 'com.tencent.tinker:tinker-android-lib:1.9.8', //Tinker熱修復(fù)
此外,我們還需要在project層級(jí)的build.gradle中添加classpath;
接下來(lái)添加tinker-support.gradle文件并在app.gradle里添加配置;
......
不一一描述,這些Bugly官方文檔里都有。下面主要講接入熱更新后,章魚(yú)App項(xiàng)目引起的改動(dòng)。
改造Application
在 tinker-support.gradle 文件中配置
enableProxyApplication = true
可以避免Application的改動(dòng),但為了更好的兼容性,Tinker官方推薦改造Application。
我們的Application改造前如下圖左半,改造后如下圖右半。
配置tinker-support
一般來(lái)說(shuō),在改造好Application后,tinker-support.gradle 無(wú)需更改即可使用。但為了在章魚(yú)項(xiàng)目下使用起來(lái)便捷,進(jìn)行了如下修改。
修改文件路徑
tinker-support默認(rèn)指定的文件路徑均位于build目錄下,而build目錄下的文件既不穩(wěn)定也不會(huì)同步到git服務(wù)器。這很容易讓我們發(fā)布線(xiàn)上包后丟失關(guān)鍵文件(用于生成對(duì)應(yīng)補(bǔ)丁包的文件),即打包后在 app/build/bakApk/日期 目錄下生成的如下文件:
app-release.apk (必有,預(yù)發(fā)布為app-prerelease.apk )
app-release-mapping.txt (開(kāi)啟混淆后會(huì)有)
app-release-R.txt (必有,預(yù)發(fā)布為app-prerelease-R.apk )
這些文件大多數(shù)時(shí)候是無(wú)用的,每次運(yùn)行項(xiàng)目或打包都會(huì)生成。我們真正需要的是線(xiàn)上包對(duì)應(yīng)的這些文件。
所以,讓tinker-support生成文件的路徑不變,將待修復(fù)apk的目錄修改為 app/bakApk/app-last-release 。
這樣,每次我們發(fā)布線(xiàn)上包后,將上述生成文件復(fù)制一份并替換到 app/bakApk/app-last-release 目錄下即可。
自動(dòng)修改tinkerId
每次打補(bǔ)丁或發(fā)布線(xiàn)上包,都需要修改tinkerId,并保證其唯一性。 我們采用如下格式:
"r" + generateDate()
例如 r-05301455 。
提供便利的測(cè)試(配置 tinker-support-prerelease.gradle 文件)
以上兩項(xiàng)配置保證了線(xiàn)上補(bǔ)丁發(fā)布的便利性,但在發(fā)布線(xiàn)上補(bǔ)丁前,我們希望對(duì)事情有所掌控。這時(shí),我們可以先測(cè)試預(yù)發(fā)布環(huán)境補(bǔ)丁效果。
為了方便,將 tinker-support.gradle 復(fù)制一份命名為 tinker-support-prerelease.gradle ,將其基準(zhǔn)包目錄修改為 app/bakApk/app-last-release ,并修改相應(yīng)文件名。
為了使tinkerId唯一且與線(xiàn)上補(bǔ)丁保持差異,采用如下格式:
"pr" + generateDate()
例如 pr-05301455 。
最后,在 app/build.gradle 文件中做如下修改(定義isReleaseTask()方法用于判斷是否為正式環(huán)境),根據(jù)任務(wù)類(lèi)型自動(dòng)引入相對(duì)應(yīng)的tinker-support配置。
if (isReleaseTask(gradle.startParameter.taskNames))
apply from: 'tinker-support.gradle'//tinker線(xiàn)上配置
else
apply from: 'tinker-support-prerelease.gradle' //tinker測(cè)試預(yù)發(fā)布包補(bǔ)丁配置。
發(fā)包清單
- 修改gradle配置,如versionName, versionCode等(tinker-support文件切換及tinkerId修改已自動(dòng)化);
- walle打包(Tinker支持walle多渠道包熱修復(fù));
- 將剛才 app/build/bakApk/日期 目錄下生成的文件備份到 app/bakApk/app-last-release 目錄(切記,只有確認(rèn)發(fā)布的線(xiàn)上包才這么做);
- 打tag,并將代碼提交至服務(wù)器。
發(fā)補(bǔ)丁清單
Tinker補(bǔ)丁不具有即時(shí)性,需要app收到補(bǔ)丁后下次啟動(dòng)才會(huì)生效。
Tinker補(bǔ)丁支持修改gradle文件與資源文件。建議補(bǔ)丁與基準(zhǔn)包(待修復(fù)包)保持一致的versionName, versionCode。
此外,Tinker對(duì)Manifest的修改支持性不好,建議補(bǔ)丁包別動(dòng)Manifest,若需要改動(dòng),請(qǐng)先在預(yù)發(fā)布環(huán)境下測(cè)試補(bǔ)丁的效果。
補(bǔ)丁發(fā)布步驟:
- 待發(fā)布代碼測(cè)試通過(guò);
- 生成預(yù)發(fā)布環(huán)境補(bǔ)丁包;
- 發(fā)布預(yù)發(fā)布環(huán)境補(bǔ)丁包并觀察效果;
——若3順利通過(guò),則繼續(xù)向下執(zhí)行,否則break。 - 生成線(xiàn)上補(bǔ)丁包;
- 灰度發(fā)布線(xiàn)上補(bǔ)丁包并觀察效果;
——若5順利通過(guò),則繼續(xù)向下執(zhí)行,否則break。 - 全量發(fā)布線(xiàn)上補(bǔ)丁包。
第2、3步是對(duì)補(bǔ)丁是否能生效的測(cè)試,約耗時(shí)15~30分鐘。理論上這兩步是可以省去的,在你確保改動(dòng)代碼被Tinker支持的情況下。不過(guò),不建議如此,熱修復(fù)依然存在許多問(wèn)題,在預(yù)發(fā)布環(huán)境先行測(cè)試補(bǔ)丁效果具有必要性。
如何生成補(bǔ)丁
線(xiàn)上補(bǔ)丁與測(cè)試補(bǔ)丁生成的差異主要體現(xiàn)在配置上。
生成測(cè)試補(bǔ)丁
將代碼切回至有問(wèn)題的線(xiàn)上節(jié)點(diǎn)。
在此配置下使用walle打 prerelease 包,并備份剛剛在 app/build/bakApk/日期 目錄下生成的基準(zhǔn)文件。
安裝剛剛生成的基準(zhǔn)apk(即代碼等同于線(xiàn)上包的debug包);
代碼切回到待發(fā)布節(jié)點(diǎn)(前面幾步造成的代碼改動(dòng)不需要保存),將第2步備份好的基準(zhǔn)文件替換到 app/bakApk/app-last-prerelease 目錄。——如果早已備份好線(xiàn)上對(duì)應(yīng)的測(cè)試包,且已安裝,則之前步驟都可以省去。
-
如下圖,執(zhí)行 buildTinkerPatchPreRelease/buildTinkerPatchDebug 指令生成prerelease/debug補(bǔ)丁。
生成預(yù)發(fā)布補(bǔ)丁
生成線(xiàn)上補(bǔ)丁
因?yàn)樵诖虬鼤r(shí)已對(duì)線(xiàn)上補(bǔ)丁進(jìn)行備份,所以生成線(xiàn)上補(bǔ)丁比測(cè)試補(bǔ)丁更為簡(jiǎn)單,步驟如下。
將代碼切換至待發(fā)布補(bǔ)丁的節(jié)點(diǎn)。
保證versionName、versionCode與線(xiàn)上版本一致(以免后續(xù)升級(jí)有問(wèn)題)。
執(zhí)行 buildTinkerPatchRelease 指令生成release補(bǔ)丁。
如何發(fā)布補(bǔ)丁
生成后的補(bǔ)丁位于項(xiàng)目 app/build/outputs/patch/環(huán)境 目錄下,其中, patch_signed_7zip.apk 文件即為要發(fā)布的補(bǔ)丁。
將 patch_signed_7zip.apk 文件上傳至Bugly指定項(xiàng)目即可。
圖文請(qǐng)參照bugly官方文檔:上傳補(bǔ)丁包到平臺(tái)。
觀察補(bǔ)丁情況
每個(gè)補(bǔ)丁都對(duì)應(yīng)著特定的一個(gè)apk,比如前面提到的線(xiàn)上apk或調(diào)試apk,在裝有該apk的手機(jī)上觀察補(bǔ)丁的下發(fā)與生效。補(bǔ)丁生效需app重啟。
如何驗(yàn)證?
為了便于驗(yàn)證,在 build.gradle 里添加一個(gè)字段 APK_DATE
buildConfigField "String", "APK_DATE", ""${generateDate()}""
這樣,APK_DATE 即為apk的構(gòu)建時(shí)間(即我們用指令生成該apk或其最新補(bǔ)丁的時(shí)間);
在設(shè)置頁(yè)面連擊版本號(hào)7次,即可觀察到相關(guān)信息 "生成時(shí):" + BuildConfig.APK_DATE。我們根據(jù)該時(shí)間信息可以很輕松地判定出當(dāng)前包是否為補(bǔ)丁包。