所謂熱修復(fù),簡(jiǎn)單來說就是不以下載新版本apk的方式來修改應(yīng)用的bug,而是在應(yīng)用啟動(dòng)后從服務(wù)器下拉補(bǔ)丁包實(shí)現(xiàn)動(dòng)態(tài)修復(fù)bug症昏。所以在應(yīng)用出現(xiàn)bug后,我們只需要打一個(gè)補(bǔ)丁父丰,用戶無需下載安裝新的版本肝谭。主要是針對(duì)一些緊急的bug的修復(fù)。
修復(fù)bug蛾扇,首先我們要能夠獲取應(yīng)用出現(xiàn)的bug攘烛。而應(yīng)用是安裝在用戶手中的,開發(fā)人員是無法直接獲取的镀首,所以我們要收集用戶端出現(xiàn)的bug坟漱。有一些三方的開源庫(kù)已經(jīng)實(shí)現(xiàn)了改功能,如:騰訊的buglay,這里我們自己簡(jiǎn)單實(shí)現(xiàn)一下更哄。
收集異常
如果我們要收集芋齿,那么首先能夠捕獲到異常,然后現(xiàn)將異常信息保存在本地文件中成翩,等應(yīng)用再次啟動(dòng)聯(lián)網(wǎng)后上傳到服務(wù)器即可觅捆。
注意:我們不僅保存異常的信息,還應(yīng)該將應(yīng)用的一些信息麻敌,如:版本號(hào)等栅炒;手機(jī)信息,如:手機(jī)型號(hào)术羔,系統(tǒng)版本等保存职辅,因?yàn)閼?yīng)用在不同型號(hào)的手機(jī)上可能存在差異化。這樣更有利于我們的調(diào)試聂示。
Thread.UncaughtExceptionHandler
這是系統(tǒng)給我們提供的一個(gè)接口,如果我們想全局捕獲異常簇秒,只要實(shí)現(xiàn)該接口即可鱼喉。
下面看一下具體的代碼:
public class ExceptionCrashHandler implements Thread.UncaughtExceptionHandler {
private static ExceptionCrashHandler instance;
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultExceptionHandler;
//構(gòu)造方法私有化
private ExceptionCrashHandler() {}
/**
* 獲取實(shí)例
* @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)用下次啟動(dòng)上線后上傳到服務(wù)器
saveInfoToSd(throwable);
}
這里我們采用的是單例模式扛禽,實(shí)現(xiàn)UncaughtExceptionHandler接口需要重寫uncaughtException(Thread thread, Throwable throwable) 方法锋边,該方法在出現(xiàn)異常時(shí),自動(dòng)回調(diào)编曼。我們需要在里面實(shí)現(xiàn)我們的邏輯豆巨,主要是將異常的信息保存在本地。我們還調(diào)用了mDefaultExceptionHandler.uncaughtException()方法掐场,只要是執(zhí)行默認(rèn)的異常處理往扔,方便我們的調(diào)試。否則我們?cè)诤笈_(tái)的日志中就看不到異常輸出了熊户。
簡(jiǎn)單測(cè)試
工具類已經(jīng)寫好萍膛,我們簡(jiǎn)單測(cè)試一下,頁(yè)面上有一個(gè)按鈕嚷堡,當(dāng)點(diǎn)擊按鈕時(shí)執(zhí)行下面的代碼:
public void btTest(View view){
int num = 2 / 0;//該代碼一定會(huì)拋出異常蝗罗。
}
阿里熱修復(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 : 簽名別名密碼(這樣一般和密鑰密碼一致)