Android熱更新之初探

什么是熱修復?

熱修復提出于2014年,興起于2016年,尤其是在Instant run 問世以后,各種熱修復技術(shù)相繼涌出。

是一種擺脫傳統(tǒng)發(fā)版方案直接使用補丁來更新app內(nèi)容,不需要重新下載安裝apk等略過一系列繁瑣過程的新興技術(shù),目前國內(nèi)部分成熟App都擁有自己的熱修復技術(shù),如:手淘、QQ、微信、美團、餓了么等。

熱修復有什么優(yōu)勢&為什么要使用熱修復?

來看一個場景:公司一個項目A在上線后發(fā)現(xiàn)一個嚴重bug如果不緊急修復可能導致用戶流失,這種情況下如果是傳統(tǒng)的app更新就很麻煩了大概是這個流程:

這期間重新發(fā)版涉及到提交測試環(huán)節(jié),這樣修復一個bug很不及時,如果使用熱修復方案,它將變得很簡單:

其優(yōu)勢為:

無需重新發(fā)版,簡單高效

用戶無感知,無需下載新應用,代價小

修復成功率高,挽回用戶群體

熱修復是如何工作的?

2017年6月手淘聯(lián)合阿里云正式發(fā)布了新一代非侵入式Android熱修復方案 - Sophix

它能修復:代碼、資源、SO庫,下圖為Sophix與微信和餓了么熱修復技術(shù)對比表

從表中我們能知道個大概,就是Sophix似乎更值得使用一下。

分別介紹QQ空間超級不定、微信Tinker和Sophix的前身HotFix各自的工作原理。

首先了解一下apk的執(zhí)行過程:代碼被編譯Build后生成apk文件,其實在里面生成了一個classes.dex文件。

我們解壓一個apk文件如下圖:

這個classes.dex就是所有代碼的集合,是一個可執(zhí)行文件,android運行apk實質(zhì)是解壓apk運行里面的這個的dex文件。

apk首次運行的時候會對這個dex文件進行優(yōu)化,優(yōu)化后生成一個odex文件,存在于緩存中,下次再啟動就直接打開這個odex文件,達到快速打開目的。而執(zhí)行apk的過程就是遍歷這個dex并作出相應操作的過程,遍歷后的dex方法存放在一個Elements數(shù)組中,它的長度限制是65536.即日常說的65K.

如果我們apk因為太龐大或者是引用三方庫太多導致方法數(shù)超過65K,就會報錯.

而谷歌已經(jīng)在Android 5.0開始支持Multdex.

在知道上面信息后,我們談談這三家的熱修復是如何實現(xiàn)的

1.QQ空間超級補?。夯贒EX分包方案,使用了多DEX加載的原理,大致的過程就是:把BUG方法修復以后,放到一個單獨的DEX里,插入到dexElements數(shù)組的最前面,讓虛擬機去加載修復完后的方法。

當patch.dex中包含Test.class時就會優(yōu)先加載,在后續(xù)的DEX中遇到Test.class的話就會直接返回而不去加載,這樣就達到了修復的目的.

2.微信Tinker:微信針對QQ空間超級補丁技術(shù)的不足提出了一個提供DEX差量包,整體替換DEX的方案。主要的原理是與QQ空間超級補丁技術(shù)基本相同,區(qū)別在于不再將patch.dex增加到elements數(shù)組中,而是差量的方式給出patch.dex,然后將patch.dex與應用的classes.dex合并,然后整體替換掉舊的DEX文件,以達到修復的目的。

3.AndFix:不同于QQ空間超級補丁技術(shù)和微信Tinker通過增加或替換整個DEX的方案,提供了一種運行時在Native修改Filed指針的方式,實現(xiàn)方法的替換,達到即時生效無需重啟,對應用無性能消耗的目的。

AndFix與HotFix的關(guān)系如下:

AndFix實現(xiàn)原理:

AndFix實現(xiàn)過程:

更詳細的說明戳這里:三大流派之簡單對比

阿里云Sophix熱修復之簡單使用

Sophix集成示例:

第一步:找到Project的build.gradle文件,在allProjects節(jié)點下加上如下代碼:

repositories {? ? ? ? ? maven { url"http://maven.aliyun.com/nexus/content/repositories/releases"}}

第二步:找到Module的build.gradle文件,添加依賴:

compile'com.aliyun.ams:alicloud-android-hotfix:3.0.7'

然后同步project

第三步:添加權(quán)限,SDK使用到以下權(quán)限

-->

READ_EXTERNAL_STORAGE/ACCESS_WIFI_STATE 權(quán)限屬于Dangerous Permissions,自行做好android6.0以上的運行時權(quán)限獲取

第四步:密鑰等配置,在application節(jié)點下加入以下配置:

第五步:登錄阿里云熱修復管理控制臺,填入對應3個value

第六步:代碼集成

在Application的attachBaseContext方法里加入Sophix初始化

@OverrideprotectedvoidattachBaseContext(Context base){super.attachBaseContext(base);? ? ? ? SophixManager.getInstance().setContext(this)? ? ? ? ? ? ? ? .setAppVersion(getAppVersion())? ? ? ? ? ? ? ? .setAesKey(null)? ? ? ? ? ? ? ? .setEnableDebug(true)? ? ? ? ? ? ? ? .setPatchLoadStatusStub(newPatchLoadStatusListener() {@OverridepublicvoidonLoad(finalintmode,finalintcode,finalString info,finalinthandlePatchVersion){// 補丁加載回調(diào)通知if(code == PatchStatus.CODE_LOAD_SUCCESS) {// 表明補丁加載成功}elseif(code == PatchStatus.CODE_LOAD_RELAUNCH) {// 表明新補丁生效需要重啟. 開發(fā)者可提示用戶或者強制重啟;// 建議: 用戶可以監(jiān)聽進入后臺事件, 然后應用自殺}elseif(code == PatchStatus.CODE_LOAD_FAIL) {// 內(nèi)部引擎異常, 推薦此時清空本地補丁, 防止失敗補丁重復加載SophixManager.getInstance().cleanPatches();? ? ? ? ? ? ? ? ? ? ? ? }else{// 其它錯誤信息, 查看PatchStatus類說明}? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }).initialize();? ? }@OverridepublicvoidonCreate(){super.onCreate();? ? ? ? ......// queryAndLoadNewPatch不可放在attachBaseContext 中,否則無網(wǎng)絡權(quán)限,建議放在后面任意時刻,如onCreate中SophixManager.getInstance().queryAndLoadNewPatch();}

自此SDK的集成已經(jīng)差不多完成,官方給出了很詳細的集成方法,官方集成文檔

第七步:生成熱修復補丁

我們直接看官方文檔這里面寫的很詳細,細到每個設置每個參數(shù)都有說明

第八步:調(diào)試并發(fā)布補丁

首先我們需要上傳補丁到阿里云管理后臺,點此查看詳細操作

接下來是對補丁的調(diào)試,點此查看詳細操作

調(diào)試沒毛病后,發(fā)布補丁,參考管理后臺使用說明的step5

作者:luciandun

鏈接:http://www.itdecent.cn/p/a4bf979cce3b

來源:簡書

簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容