Android熱修復(fù)技術(shù)對(duì)比

2015年以來,Android開發(fā)領(lǐng)域里對(duì)熱修復(fù)技術(shù)的討論和分享越來越多,同時(shí)也出現(xiàn)了一些不同的解決方案,如QQ空間補(bǔ)丁方案、阿里AndFix以及微信Tinker,它們?cè)谠砀饔胁煌m用場(chǎng)景各異,到底采用哪種方案,通過介紹QQ空間補(bǔ)丁、Tinker以及基于AndFix的阿里百川HotFix技術(shù)的原理分析和橫向比較

一、熱修復(fù)的技術(shù)的發(fā)展史

1、熱修復(fù)技術(shù)的由來

從傳統(tǒng)的開發(fā)流程來講,存在很多弊端:

  • 重新發(fā)版本的代價(jià)太大
  • 用戶下載安裝成本太高
  • bug修復(fù)不及時(shí),用戶體驗(yàn)太差

2、熱修復(fù)開發(fā)流程

上線版本--用戶安裝--發(fā)現(xiàn)bug--緊急修復(fù)--打出補(bǔ)丁,推送給用戶--自動(dòng)拉取補(bǔ)丁修復(fù)

而熱修復(fù)的開發(fā)流程顯得更加靈活,優(yōu)勢(shì)很多:

  • 無需重新發(fā)版,實(shí)時(shí)高效熱修復(fù)
  • 用戶無感知修復(fù),無需下載新的應(yīng)用,代價(jià)小
  • 修復(fù)成功率高,把損失降到最低

二、三大主流的熱修復(fù)技術(shù)

1、QQ空間超級(jí)補(bǔ)丁技術(shù)

超級(jí)補(bǔ)丁技術(shù)基于DEX分包方案,使用了多DEX加載的原理,大致的過程就是:

  • 把BUG方法修復(fù)以后,放到一個(gè)單獨(dú)的DEX里,插入到dexElements數(shù)組的最前面,讓虛擬機(jī)去加載修復(fù)完后的方法。當(dāng)patch.dex中包含Test.class時(shí)就會(huì)優(yōu)先加載,在后續(xù)的DEX中遇到Test.class的
    話就會(huì)直接返回而不去加載,這樣就達(dá)到了修復(fù)的目的。
  • 但是有一個(gè)問題是,當(dāng)兩個(gè)調(diào)用關(guān)系的類不在同一個(gè)DEX時(shí),就會(huì)產(chǎn)生異常報(bào)錯(cuò)。我們知道,在APK安裝時(shí),虛擬機(jī)需要將classes.dex優(yōu)化成odex文件,然后才會(huì)執(zhí)行。在這個(gè)過程中,會(huì)進(jìn)行類的verify
    操作,如果調(diào)用關(guān)系的類都在同一個(gè) DEX中的話就會(huì)被打上CLASS_ISPREVERIFIED的標(biāo)志,然后才會(huì)寫入odex文件。
  • 所以,為了可以正常的進(jìn)行打補(bǔ)丁修復(fù),必須避免類被打上CLASS_ISPREVERIFIED 標(biāo)志,具體的做法就是單獨(dú)放一個(gè)類在另外DEX中,讓其他類調(diào)用。

修復(fù)的主要步驟:

  • 可以看出是通過獲取到當(dāng)前應(yīng)用的Classloader
  • 通過反射調(diào)用pathList的dexElements方法把patch.dex轉(zhuǎn)化為Element[]
  • 兩個(gè)Element[]進(jìn)行合并,把patch.dex放到最前面去
  • 加載Element[],達(dá)到修復(fù)目的


    image.png
image.png

優(yōu)勢(shì):

  • 沒有整合包(這是和下面微信的Tinker比起來),產(chǎn)物表較小,比較靈活
  • 可以實(shí)現(xiàn)類替換,兼容性高。(某些三星手機(jī)不起作用)

不足:

  • 不會(huì)及時(shí)生效,必須通過重啟才能生效。
  • 時(shí)嚴(yán)重,會(huì)增加啟動(dòng)時(shí)間,導(dǎo)致ANR的概率明顯增大

2、微信Tinker

  • 微信針對(duì)QQ空間超級(jí)補(bǔ)丁技術(shù)的不足提出了一個(gè)提供DEX差量包,整體替換DEX的方案。主要的原理是與QQ空間超級(jí)補(bǔ)丁技術(shù)基本相同,區(qū)別在于不再將 patch.dex增加到elements數(shù)組中,而是差量
    的方式給出patch.dex,然后將patch.dex與應(yīng)用的classes.dex合并,然后整體替換掉舊的DEX,達(dá)
    到修復(fù)的目的。
image.png

image.png

優(yōu)勢(shì):

  • 合成整包,不用在構(gòu)造函數(shù)插入代碼,防止verify,verify和opt在編譯期間就已經(jīng)完成,不會(huì)在運(yùn)行期間進(jìn)行
  • 性能提高。兼容性和穩(wěn)定性比較高
  • 開發(fā)者透明,不需要對(duì)包進(jìn)行額外處理

劣勢(shì):

  • 與超級(jí)補(bǔ)丁技術(shù)一樣,不支持即時(shí)生效,必須通過重啟應(yīng)用的方式才能效
  • 需要給應(yīng)用開啟新的進(jìn)程才能進(jìn)行合并,并且很容易因?yàn)閮?nèi)存消耗等原因合并失敗。
  • 合并時(shí)占用額外磁盤空間,對(duì)于多DEX的應(yīng)用來說,如果修改了多個(gè)DEX文件,就需要下發(fā)多個(gè)patch.dex與對(duì)應(yīng)
    的classes.dex進(jìn)行合并操作時(shí)這種情況會(huì)更嚴(yán)重,因此合并過程的失敗率也會(huì)更高

3、阿里百川HotFix

  • 阿里百川推出的熱修復(fù)HotFix服務(wù),相對(duì)于QQ空間超級(jí)補(bǔ)丁技術(shù)和微信Tinker來說,定位于緊急bug修復(fù)的場(chǎng)景下,能夠最及時(shí)的修復(fù)bug,下拉補(bǔ)丁立即生效無需等待。
    實(shí)現(xiàn)的原理:
  • AndFix不同于QQ空間超級(jí)補(bǔ)丁技術(shù)和微信Tinker通過增加或替換整個(gè)DEX的方案,提供了一種運(yùn)行時(shí)在Native修改Filed指針的方式,實(shí)現(xiàn)方法的替
    換,達(dá)到即時(shí)生效無需重啟,對(duì)應(yīng)用無性能消耗的目的

實(shí)現(xiàn)的過程步驟:

  • 打開鏈接庫操作句柄,獲得native層內(nèi)部函數(shù),得到ClassObject對(duì)象
  • 修改訪問權(quán)限屬性為public
  • 得到新舊方法的指針,新的方法指向目標(biāo)方法,實(shí)現(xiàn)方法的替換
image.png

image.png

image.png

優(yōu)勢(shì):

  • bug的修復(fù)的及時(shí)性
  • 補(bǔ)丁包同樣采用差量技術(shù),生成patch體積最小
  • 對(duì)應(yīng)用無入侵,幾乎無性能損耗

不足:

  • 不支持新增字段,以及修改<init>方法,也不支持對(duì)資源的替換。
  • 由于廠商的自定義ROM,對(duì)少數(shù)機(jī)型暫不支持。

三、總結(jié):

  • QQ空間超級(jí)補(bǔ)丁技術(shù)和微信Tinker 支持新增類和資源的替換,在一些功能化的更新上更為強(qiáng)大,但對(duì)應(yīng)用的性能和穩(wěn)定會(huì)有的一定的影響;阿里百川HotFix雖然暫時(shí)不支持新增類
    和資源的替換,對(duì)新功能的發(fā)布也有所限制,但是作為一項(xiàng)定位為線上緊急BUG的熱修復(fù)的服務(wù)來說,能夠真正做到BUG即時(shí)修復(fù)用戶無感知,同時(shí)保證對(duì)應(yīng)用性能不產(chǎn)生不必要的損
    耗,在熱修復(fù)方面不失為一個(gè)好的選擇


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

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

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