所謂熱修復(fù),簡單來說就是不以下載新版本apk的方式來修改應(yīng)用的bug,而是在應(yīng)用啟動后從服務(wù)器下拉補(bǔ)丁包實現(xiàn)動態(tài)修復(fù)bug。所以在應(yīng)用出現(xiàn)bug后,我們只需要打一個補(bǔ)丁,用戶無需下載安裝新的版本。主要是針對一些緊急的bug的修復(fù)。


修復(fù)bug,首先我們要能夠獲取應(yīng)用出現(xiàn)的bug。而應(yīng)用是安裝在用戶手中的,開發(fā)人員是無法直接獲取的,所以我們要收集用戶端出現(xiàn)的bug。有一些三方的開源庫已經(jīng)實現(xiàn)了改功能,如:騰訊的buglay,這里我們自己簡單實現(xiàn)一下。
收集異常
如果我們要收集,那么首先能夠捕獲到異常,然后現(xiàn)將異常信息保存在本地文件中,等應(yīng)用再次啟動聯(lián)網(wǎng)后上傳到服務(wù)器即可。
注意:我們不僅保存異常的信息,還應(yīng)該將應(yīng)用的一些信息,如:版本號等;手機(jī)信息,如:手機(jī)型號,系統(tǒng)版本等保存,因為應(yīng)用在不同型號的手機(jī)上可能存在差異化。這樣更有利于我們的調(diào)試。
Thread.UncaughtExceptionHandler
這是系統(tǒng)給我們提供的一個接口,如果我們想全局捕獲異常,只要實現(xiàn)該接口即可。
下面看一下具體的代碼:
public class ExceptionCrashHandler implements Thread.UncaughtExceptionHandler {
private static ExceptionCrashHandler instance;
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultExceptionHandler;
//構(gòu)造方法私有化
private ExceptionCrashHandler() {}
/**
* 獲取實例
* @return
*/
public static ExceptionCrashHandler getInstance() {
if (instance == null) {
synchronized (ExceptionCrashHandler.class) {
if (instance == null) {
instance = new ExceptionCrashHandler();
}
}
}
return instance;
}
/**
* 初始化操作
* @param context
*/
public void init(Context context) {
this.mContext = context;
//設(shè)置全局捕獲異常類為本類
Thread.currentThread().setUncaughtExceptionHandler(this);
//獲取系統(tǒng)默認(rèn)的全局異常捕獲類,用于輸出異常信息
mDefaultExceptionHandler = Thread.currentThread().getDefaultUncaughtExceptionHandler();
}
/**
* 全局捕獲異常
*/
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
mDefaultExceptionHandler.uncaughtException(thread, throwable);//系統(tǒng)默認(rèn)的處理(打印異常信息)
//保存信息到文件,等應(yīng)用下次啟動上線后上傳到服務(wù)器
saveInfoToSd(throwable);
}
這里我們采用的是單例模式,實現(xiàn)UncaughtExceptionHandler接口需要重寫uncaughtException(Thread thread, Throwable throwable) 方法,該方法在出現(xiàn)異常時,自動回調(diào)。我們需要在里面實現(xiàn)我們的邏輯,主要是將異常的信息保存在本地。我們還調(diào)用了mDefaultExceptionHandler.uncaughtException()方法,只要是執(zhí)行默認(rèn)的異常處理,方便我們的調(diào)試。否則我們在后臺的日志中就看不到異常輸出了。
簡單測試
工具類已經(jīng)寫好,我們簡單測試一下,頁面上有一個按鈕,當(dāng)點擊按鈕時執(zhí)行下面的代碼:
public void btTest(View view){
int num = 2 / 0;//該代碼一定會拋出異常。
}

阿里熱修復(fù)-AndFix
1.添加依賴
2.使用
patchManager = new PatchManager(context);
patchManager.init(appversion);
patchManager.loadPatch();//加載之前的補(bǔ)丁
patchManager.addPatch(path);//添加新的補(bǔ)丁
path:是補(bǔ)丁包的路徑
生成補(bǔ)丁包
andfix給我們提供了生成補(bǔ)丁包的工具

通過命令生成補(bǔ)丁包
apkpatch.bat -f <new> -t <old> -o <output> -k <keystore> -p <****> -a <alias> -e <****>
-f : 沒有Bug的新版本apk
-t : 有bug的舊版本apk
-o : 生成的補(bǔ)丁文件所放的文件夾
-k : 簽名打包密鑰
-p : 簽名打包密鑰密碼
-a : 簽名密鑰別名
-e : 簽名別名密碼(這樣一般和密鑰密碼一致)
