Android熱修復(fù)技術(shù)選型的三大流派解析
2015年以來,Android開發(fā)領(lǐng)域里對(duì)熱修復(fù)技術(shù)的討論和分享越來越多,同時(shí)也出現(xiàn)了一些不同的解決方案,如QQ空間補(bǔ)丁方案、阿里AndFix以及微信Tinker,它們?cè)谠砀饔胁煌?,適用場(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ù)的主要步驟:
1、可以看出是通過獲取到當(dāng)前應(yīng)用的Classloader
2、通過反射調(diào)用pathList的dexElements方法把patch.dex轉(zhuǎn)化為Element[]
3、兩個(gè)Element[]進(jìn)行合并,把patch.dex放到最前面去
4、加載Element[],達(dá)到修復(fù)目的

image.png

image.png
優(yōu)勢(shì):
1、沒有整合包(這是和下面微信的Tinker比起來),產(chǎn)物表較小,比較靈活
2、可以實(shí)現(xiàn)類替換,兼容性高。(某些三星手機(jī)不起作用)
不足:
1、不會(huì)及時(shí)生效,必須通過重啟才能生效。
2、耗時(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ì):
1、合成整包,不用在構(gòu)造函數(shù)插入代碼,防止verify,verify和opt在編
譯期間就已經(jīng)完成,不會(huì)在運(yùn)行期間進(jìn)行
2、性能提高。兼容性和穩(wěn)定性比較高
3、開發(fā)者透明,不需要對(duì)包進(jìn)行額外處理(不需要在構(gòu)造函數(shù)中添加代碼)
劣勢(shì):
1、與超級(jí)補(bǔ)丁技術(shù)一樣,不支持即時(shí)生效,必須通過重啟應(yīng)用的方式才能效
2、需要給應(yīng)用開啟新的進(jìn)程才能進(jìn)行合并,并且很容易因?yàn)閮?nèi)存消耗等原因合并失敗。
3、合并時(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)的過程步驟:
1、打開鏈接庫操作句柄,獲得native層內(nèi)部函數(shù),得到ClassObject對(duì)象
2、修改訪問權(quán)限屬性為public(Classloader 不同)
3、得到新舊方法的指針,新的方法指向目標(biāo)方法,實(shí)現(xiàn)方法的替換

image.png

image.png

image.png
優(yōu)勢(shì):
1、bug的修復(fù)的及時(shí)性
2、補(bǔ)丁包同樣采用差量技術(shù),生成patch體積最小
3、對(duì)應(yīng)用無入侵,幾乎無性能損耗
不足:
1、不支持四大組件的新增和修改以及主題資源的配置。
2、由于是其平臺(tái)內(nèi)部是判別是熱修復(fù)還是冷修復(fù),所以有時(shí)候可能無法達(dá)到自己想要的結(jié)果。
三、總結(jié):
QQ空間超級(jí)補(bǔ)丁技術(shù)和微信Tinker 支持新增類和資源的替換,但對(duì)應(yīng)用的性能和穩(wěn)定會(huì)有的一定的影響;阿里百川HotFix雖然
支持新增類和資源的替換,但也有所限制,但是作為一項(xiàng)定位為線上緊急
BUG的熱修復(fù)的服務(wù)來說,能夠真正做到BUG即時(shí)修復(fù)用戶無感知,同時(shí)保證對(duì)應(yīng)用性能
不產(chǎn)生不必要的損耗,在熱修復(fù)方面不失為一個(gè)好的選擇

性能比較@2x.png