一先朦、Android 中的兩大流派:
1次洼、Native Hook 流派:改寫(xiě) 方法:淘寶的Dexposed,支付寶的AndFix 、Rebust辛萍、instantRun ?
Dexposed只只吃Android 5.0之下悯姊,不支持全平臺(tái)。
2叹阔、dex hack 流派:QQ超級(jí)補(bǔ)丁挠轴,Tinker 。
二耳幢、方案分析
http://www.chinaz.com/news/2016/0912/579753.shtml
1、QQ空間超級(jí)補(bǔ)杜菲 :
(1)mutilDex機(jī)制睛藻。QQ空間超級(jí)補(bǔ)丁方案是基于android dex分包方案。
分包機(jī)制的來(lái)由(邢隧?)dexopt 店印、65K限制。
當(dāng)一個(gè)apk在安裝的時(shí)候倒慧,apk中的classes.dex會(huì)被虛擬機(jī)(dexopt)優(yōu)化成odex文件按摘,然后才會(huì)拿去執(zhí)行包券。
(2)ClassLoader 類(lèi)加載機(jī)制。ClassLoader機(jī)制是QQ空間超級(jí)補(bǔ)丁方案的基石炫贤。
tm一個(gè)ClassLoader可以包含多個(gè)dex文件溅固,每個(gè)dex文件就是一個(gè) Element,多個(gè)dex文件排列形成一個(gè)有序的數(shù)組DexElements,當(dāng)查找某個(gè)類(lèi)時(shí)會(huì)按照順序遍歷dex文件兰珍,然后從當(dāng)前遍歷的dex文件中找類(lèi)侍郭,如果找到了則返回,如果找不到則從下一個(gè)dex查找掠河。理論上亮元,如果在不同的dex中有相同的類(lèi)存在,那么優(yōu)先選擇排在前面的dex文件的類(lèi)唠摹。
當(dāng)patch.dex中包含Test.class時(shí)就會(huì)優(yōu)先加載爆捞,在后續(xù)的DEX中遇到Test.class的話(huà)就會(huì)直接返回而不去加載,這樣就達(dá)到了修復(fù)的目的勾拉。
(3)副作用:CLASS_ISPREVERIFIED 標(biāo)志煮甥。
防止類(lèi)被打上CLASS_ISPREVERIFIED標(biāo)志。
最終空間的方案是往所有類(lèi)的構(gòu)造函數(shù)里面插入了一段代碼望艺,如下:
if (ClassVerifier.PREVENT_VERIFY) {
System.out.println(AntilazyLoad.class);
}
這樣當(dāng)安裝apk的時(shí)候苛秕,classes.dex內(nèi)的類(lèi)都會(huì)引用一個(gè)在不相同dex中的AntilazyLoad類(lèi),這樣就防止了類(lèi)被打上CLASS_ISPREVERIFIED的標(biāo)志了找默,只要沒(méi)被打上這個(gè)標(biāo)志的類(lèi)都可以進(jìn)行打補(bǔ)丁操作艇劫。
優(yōu)勢(shì):
1.? 沒(méi)有合成整包(和微信Tinker比起來(lái)),產(chǎn)物比較小惩激,比較靈活
2.? 可以實(shí)現(xiàn)類(lèi)替換店煞,兼容性高。(某些三星手機(jī)不起作用)
不足:
1. 不支持即時(shí)生效风钻,必須通過(guò)重啟才能生效顷蟀。
2. 為了實(shí)現(xiàn)修復(fù)這個(gè)過(guò)程,必須在應(yīng)用中加入兩個(gè)dex!dalvikhack.dex中只有一個(gè)類(lèi)骡技,對(duì)性能影響不大鸣个,但是對(duì)于patch.dex來(lái)說(shuō),修復(fù)的類(lèi)到了一定數(shù)量布朦,就需要花不少的時(shí)間加載囤萤。對(duì)手淘這種航母級(jí)應(yīng)用來(lái)說(shuō),啟動(dòng)耗時(shí)增加2s以上是不能夠接受的事是趴。
3. 在ART模式下涛舍,如果類(lèi)修改了結(jié)構(gòu),就會(huì)出現(xiàn)內(nèi)存錯(cuò)亂的問(wèn)題唆途。為了解決這個(gè)問(wèn)題富雅,就必須把所有相關(guān)的調(diào)用類(lèi)掸驱、父類(lèi)子類(lèi)等等全部加載到patch.dex中,導(dǎo)致補(bǔ)丁包異常的大没佑,進(jìn)一步增加應(yīng)用啟動(dòng)加載的時(shí)候毕贼,耗時(shí)更加嚴(yán)重。
2图筹、微信 Tinker
在編譯時(shí)通過(guò)新舊兩個(gè)Dex生成差異path.dex帅刀。在運(yùn)行時(shí),將差異patch.dex重新跟原始安裝包的舊Dex還原為新的Dex远剩。這個(gè)過(guò)程可能比較耗費(fèi)時(shí)間與內(nèi)存扣溺,所以我們是單獨(dú)放在一個(gè)后臺(tái)進(jìn)程:patch中。
優(yōu)勢(shì):
1.? 合成整包瓜晤,不用在構(gòu)造函數(shù)插入代碼锥余,防止verify,verify和opt在編譯期間就已經(jīng)完成痢掠,不會(huì)在運(yùn)行期間進(jìn)行驱犹。
2.? 性能提高。兼容性和穩(wěn)定性比較高足画。
3.? 開(kāi)發(fā)者透明雄驹,不需要對(duì)包進(jìn)行額外處理。
不足:
1. 與超級(jí)補(bǔ)丁技術(shù)一樣淹辞,不支持即時(shí)生效医舆,必須通過(guò)重啟應(yīng)用的方式才能生效。
2. 需要給應(yīng)用開(kāi)啟新的進(jìn)程才能進(jìn)行合并象缀,并且很容易因?yàn)閮?nèi)存消耗等原因合并失敗蔬将。
3. 合并時(shí)占用額外磁盤(pán)空間(占用Rom體積),這邊大約是你修改Dex數(shù)量的1.5倍(dexopt與dex壓縮成jar)的大醒胄恰)霞怀。
微信的這套方案并非沒(méi)有優(yōu)缺點(diǎn),它帶來(lái)的問(wèn)題有兩個(gè):
占用Rom體積莉给;這邊大約是你修改Dex數(shù)量的1.5倍(dexopt與dex壓縮成jar)的大小毙石。
一個(gè)額外的合成過(guò)程;雖然我們單獨(dú)放在一個(gè)進(jìn)程上處理颓遏,但是合成時(shí)間的長(zhǎng)短與內(nèi)存消耗也會(huì)影響最終的成功率
四胁黑、AndFix:
AndFix 提供一種運(yùn)行時(shí)在Native修改Field指針的方式,實(shí)現(xiàn)方法的替換州泊,達(dá)到即時(shí)生效無(wú)需重啟,對(duì)應(yīng)用無(wú)性能損耗的目的漂洋。
1遥皂、原理如圖:
2力喷、實(shí)現(xiàn)過(guò)程:
優(yōu)勢(shì):
1.? BUG修復(fù)的即時(shí)性
2.? 補(bǔ)丁包同樣采用差量技術(shù),生成的PATCH體積小
3.? 對(duì)應(yīng)用無(wú)侵入演训,幾乎無(wú)性能損耗
不足:
1.? 不支持新增字段弟孟,以及修改方法,也不支持對(duì)資源的替換样悟。
2.? 由于廠商的自定義ROM拂募,對(duì)少數(shù)機(jī)型暫不支持。
Android 熱補(bǔ)丁展望:
2窟她、遠(yuǎn)端調(diào)試:如果 能夠?qū)崿F(xiàn)真對(duì)某個(gè)用戶(hù)下發(fā)陈症,就可以作為遠(yuǎn)端調(diào)試功能。
一入Android深似海情组,Android開(kāi)發(fā)的另外一個(gè)痛是機(jī)型的碎片化窃植。我們也許都會(huì)遇到”本地不復(fù)現(xiàn)”溉仑,”日志查不出”,”聯(lián)系用戶(hù)不鳥(niǎo)你”的煩惱论咏。所以補(bǔ)丁機(jī)制非常適合使用在遠(yuǎn)端調(diào)試上。即我們需要具備只特定用戶(hù)發(fā)送補(bǔ)丁的能力颁井,這對(duì)我們查找問(wèn)題非常有幫助厅贪。
3、數(shù)據(jù)統(tǒng)計(jì):
熱補(bǔ)丁無(wú)論在普通的數(shù)據(jù)統(tǒng)計(jì)還是ABTest都有著非常大的優(yōu)勢(shì)雅宾。例如若我想對(duì)同一批用戶(hù)做兩種test, 傳統(tǒng)方式無(wú)法讓這批用戶(hù)去安裝兩個(gè)版本养涮。使用補(bǔ)丁技術(shù),我們可以方便的對(duì)同一批用戶(hù)不停的更換補(bǔ)丁秀又。