導(dǎo)語
熱修復(fù)的特點(diǎn):無需重新發(fā)版,實(shí)時(shí)高效熱修復(fù);用戶無感知修復(fù),無需下載新的應(yīng)用,代價(jià)小;
修復(fù)成功率高,把損失降到最低。
一、熱修復(fù)開源方案和使用情況
| 方案名稱 | 方案開發(fā)公司 | 開發(fā)時(shí)間 | Github星評(píng) | |
|---|---|---|---|---|
| Robust | 美團(tuán) | 2016年 | 54 | |
| Andfix | 阿里 | 2015年 | 4994 | |
| Nuwa | 個(gè)人開發(fā)者(dex文件補(bǔ)?。?/td> | 2015年 | 2588 | |
| Dexposed | 不考慮,需要root權(quán)限 | |||
| Amigo | 餓了么(apk補(bǔ)?。?/td> | 2016年 | 1031 | |
| Tinker | 微信(apk補(bǔ)丁) | 2016年 | 7891 | |
| RocooFix | Nuwa改進(jìn)版 | 2016年 | 1299 |
Robust方案
1.原理:Robust插件對(duì)每個(gè)產(chǎn)品代碼的每個(gè)函數(shù)都在編譯打包階段自動(dòng)的插入了一段代碼,插入過程對(duì)業(yè)務(wù)開發(fā)是完全透明。

在Application中通過DexClassLoader,將補(bǔ)丁class文件事先加載,然后之后會(huì)調(diào)用新的額
class以替換舊apk中的bug class文件,通過反射進(jìn)行新代碼的調(diào)用,以達(dá)到熱修復(fù)目的。
具體過程請(qǐng)參考Android熱更新方案Robust
2.補(bǔ)丁制作
Robust的補(bǔ)丁制作,除了打包dex文件,更需要使用美團(tuán)的插件將每個(gè)class文件插入代碼,在編譯階段侵入代碼
對(duì)運(yùn)行效率等方面都有影響
*** 優(yōu)點(diǎn) ***
1.高兼容和適配性,由于是java代碼層面的替換調(diào)用,基本不涉及各個(gè)版本
的適配和虛擬機(jī)的適配。
*** 缺點(diǎn) ***
1.由于對(duì)包體中的文件進(jìn)行了代碼侵入,對(duì)運(yùn)行效率、方法數(shù)、包體積都有
影響,文件方法數(shù)變多,企業(yè)級(jí)應(yīng)用可能會(huì)涉及到65535的問題。
2.項(xiàng)目不夠成熟,文檔不夠健全。
Andfix方案
1.原理:補(bǔ)丁工具apkpatch將兩個(gè)apk做一次對(duì)比,然后找出不同的部分可以看到生成的apatch了文件,
后綴改成zip再解壓開,里面有一個(gè)dex文件。通過jadx查看一下源碼,里面就是被修復(fù)的代碼所在的類
文件,這些更改過的類都加上了一個(gè)_CF的后綴,并且變動(dòng)的方法都被加上了一個(gè)叫@MethodReplace
的annotation,通過clazz和method指定了需要替換的方法。然后客戶端sdk得到補(bǔ)丁文件
后就會(huì)根據(jù)annotation來尋找需要替換的方法。最后由JNI層調(diào)用native完成完成指針的替換。
2.補(bǔ)丁制作
官方提供apkpatch工具
apkpatch -o D:/Patch/ -k debug.keystore -p android-a androiddebugkey -e android f bug-fix.apk t release.apk
*** 優(yōu)點(diǎn) ***
1.項(xiàng)目成熟,文檔健全。
2.集成簡單
3.安全性高
*** 缺點(diǎn) ***
1.不支持YunOS
2.無法添加新類和新的字段
3.需要使用加固前的apk制作補(bǔ)丁,但是補(bǔ)丁文件很容易被反編譯,也就是修改過的類源碼容易泄露。
4.使用加固平臺(tái)可能會(huì)使熱補(bǔ)丁功能失效
Nuwa方案
1.原理:動(dòng)態(tài)加載補(bǔ)丁dex,并將補(bǔ)丁dex插入到dexElements最前面。要實(shí)現(xiàn)熱更
新,需要熱更新的類要防止被打上ISPREVERIFIED標(biāo)記
2.補(bǔ)丁制作
Gradle插件要做的事就是拿到所有class,在其構(gòu)造函數(shù)中注入Hack.class,使其直接引用另一個(gè)dex中的文件,防止被打上ISPREVERIFIED標(biāo)記。并且發(fā)版時(shí)的mapping文件以及所有class文件的hash值的文件需要保持下來打patch使用。
*** 優(yōu)點(diǎn) ***
1.項(xiàng)目成熟,文檔健全。
2.集成簡單
3.支持添加新加類和新的字段
*** 缺點(diǎn) ***
1.支持gradle1.5以下
2.需要應(yīng)用重啟后生效
Tinker
1.原理:通過新舊apk比較,使用gradle從插件生成.dex補(bǔ)丁文件(并不是真正的dex文件),補(bǔ)丁通過服務(wù)器下發(fā)后嘗試對(duì)dex文件二路歸并進(jìn)行合并,最終生成全量的dex文件,與生成補(bǔ)丁互為逆過程,生成全量dex文件后進(jìn)行optimize操作,最終生成odex文件。在Application中進(jìn)行反射調(diào)用已經(jīng)合成的dex文件。

2.補(bǔ)丁制作
使用微信gralde插件tinkerPatchRelease任務(wù)調(diào)用生成補(bǔ)丁
*** 優(yōu)點(diǎn) ***
1.項(xiàng)目成熟,文檔健全。
2.集成簡單
3.支持資源文件和so文件的修復(fù)替換
*** 缺點(diǎn) ***
1.不支持四大組件的添加
2.需要應(yīng)用重啟后生效
RocooFix
1.原理:同Nuwa,因?yàn)樽钸m合我們當(dāng)前的使用,詳細(xì)介紹下
2.補(bǔ)丁制作
使用gradle插件自動(dòng)生成包含dex的jar文件
*** 使用過程 ***
1.Application中初始化:
RocooFix.init(this);
RocooFix.applyPatch(this,path);
2.根目錄下build.gradle文件添加:
classpath 'com.dodola:rocoofix:1.2.2'
3.app中build.gradle文件中添加:
apply plugin: 'com.dodola.rocoofix'
compile 'com.dodola:rocoo:1.1'
rocoo_fix {
includePackage = ['com/xiaomi/gamecenter/wxwap']//指定將來可能需要制作補(bǔ)丁的package(就是指定插莊的范圍)
excludeClass = ['HyApplication.class']//將不需要加到patch里的類寫在這里(不需要插莊的類)
preVersionPath = '1'//注意:此項(xiàng)屬性只在需要制作補(bǔ)丁的時(shí)候才需開啟??!如果不需要制作補(bǔ)丁則需要去掉此項(xiàng)
enable = true//注意:關(guān)掉此項(xiàng)會(huì)無法生成Hash.txt文件
scanref=false//默認(rèn)為 false,開啟這個(gè)選項(xiàng)會(huì)將與補(bǔ)丁 class 相引用的 class 都打入包中來解決 ART 虛擬機(jī)崩潰問題,功能 Beta 中
}
4.更改versionCode 開啟混淆,不開混淆的話無法生成補(bǔ)丁文件,可以設(shè)定生成補(bǔ)丁的包
5.補(bǔ)丁文件為增量文件,只包含改動(dòng)的文件,補(bǔ)丁可由我們自己生成,不需要經(jīng)過cp
*** 優(yōu)點(diǎn) ***
1.項(xiàng)目成熟,文檔健全。
2.集成簡單
3.支持so文件的修復(fù)替換
4.補(bǔ)丁生成與apk無關(guān)(增量補(bǔ)丁無關(guān)性,不依賴cp等第三方)
*** 缺點(diǎn) ***
1.不支持四大組件的添加
2.需要應(yīng)用重啟后生效