什麼是熱修復呢?
熱修復是針對修復app中的bug的場景來定義的。
假設,現在用戶使用的app有個方法報錯了,那麼解決這個問題,目前有2種方式:
一:直接下載整個最新app重新安裝;二:使用增量更新的方式下載patch包合成新apk,重新安裝;
雖然增量更新的體驗更好,但是這2種方式的共同問題是都需要重新安裝。那麼,有沒有一種方式不用重新安裝app,在用戶不知不覺中就修復了bug呢?
熱修復技術就是在不重新安裝app的前提下,通過下載patch包,動態加載到內存替換有bug的方法,從而實現修復bug。
熱修復的實現原理
首先,生成新版本和舊版本的差異補丁包文件(此步驟有點類似於增量更新的第一步);
其次,使用熱修復框架的Api在Application中去嘗試加載指定路徑的補丁差異包;
最後,只需要將補丁包文件拷貝到對應路徑,打開有bug的App,在Application創建的時候就已經將補丁包文件加載到內存中並且替換了對應的方法。
不知不覺中,bug已然修復。
阿里的熱修復框架AndFix
熱修復有很多方案,其中阿里開源的AndFix使用起來比較簡單,而且比較穩定。
詳情查看github地址:https://github.com/alibaba/AndFix
阿里的AndFix框架使用步驟如下:
首先,創建一個app,模擬出bug程序:
public void show(View v){
Cat cat = new Cat();
Toast.makeText(this, cat.getName(), Toast.LENGTH_SHORT).show();
}
然後,在gradle中依賴AndFix類庫,並且在Application的onCreate方法中編寫出加載patch文件的代碼:
//經反覆測試,0.5的版本不如0.4的版本穩定,因此我們用穩定的版本
//compile 'com.alipay.euler:andfix:0.5.0@aar'
compile 'com.alipay.euler:andfix:0.5.0@aar'
添加加載patch文件的代碼:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
PatchManager patchManager = new PatchManager(this);
String appVersion = "1.0";//當前app的版本號
patchManager.init(appVersion);
//開始加載patch文件
patchManager.loadPatch();
File patchFile = new File(Environment.getExternalStorageDirectory(),"out.apatch");
try {
if(patchFile.exists()){
//指定patch文件的路徑
patchManager.addPatch(patchFile.getAbsolutePath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
此時,將帶有bug的代碼導出一份簽名過的apk文件,命名爲bug.
然後,我們在代碼中修復bug,再重新使用相同的簽名導出一份apk文件,命名爲fix.
現在,我們將2個apk文件和簽名文件一同複製到AndFix-master\tools\apkpatch-1.0.3目錄下,使用apkpatch命令產生出patch文件,命令如下:
apkpatch -f fix.apk -t bug.apk -o bug_fix -k test.jks -p 111111 -a test -e
現在將bug.apk文件裝到手機上,並將patch文件複製到sd卡指定目錄(在真實開發中,此patch文件應該是從服務器下載,並且該patch文件的後綴必須是.apatch);運行帶有bug的app,由於代碼已經在Application的onCreate中編寫了加載了patch文件的代碼,所以patch文件將會覆蓋掉帶有bug的代碼。
注意:你可能擔心補丁文件放在sd卡上不安全,萬一被用戶刪除了,不就又回到了錯誤的代碼嗎?
阿里的AndFix已經考慮了該問題,我們可以嘗試刪除sd卡的patch文件,你會發現程序的bug仍然被修復了。這是因爲AndFix框架在第一次加載補丁文件的時候,將其複製到了/data/data/包名/file目錄下,可以去該目錄找到patch文件。