使用阿里熱修復需要新增依賴
compile 'com.alipay.euler:andfix:0.5.0@aar'
熱修復的關鍵**
//初始化阿里熱修復
mpatchmanger = new patchmanager(this);
//獲取當前應用版本
mpatchmanger.loadpatch();
file patchfile = new file(environment.getexternalstoragedirectory().getabsolutepath(),"fix.apatch");
if (patchfile != null) catch (ioexception e)
}
接下來我們從這些方法開始看熱修復是怎樣實現的
mpatchmanger = new patchmanager(this);
public patchmanager(context context)
if (!mpatchdir.exists() && !mpatchdir.mkdirs()) else if (!mpatchdir.isdirectory())
sharedpreferences sp = mcontext.getsharedpreferences(sp_name,
context.mode_private);
string ver = sp.getstring(sp_version, null);
//版本校驗
cleanpatch();
} else
}
private void initpatchs()
}
addpatch
驗證檔名,對符合要求的檔名進行封裝,得到乙個個patch物件,在集合中儲存
/**
* add patch file
* * @param file
* @return patch
*/private patch addpatch(file file) catch (ioexception e)
}return patch;
}
可見mpatchmanger.init方法只是載入差分包然後進行儲存
接下來看mpatchmanger.loadpatch();
public void loadpatch() }}
進入mandfixmanager.fix(patch.getfile(),mcontext.getclassloader(),
classes);
//listclasses儲存了每個patc**件的相關資訊
public synchronized void fix(file file, classloader classloader,
listclasses)
if (clazz == null)
return clazz;}};
enumerationentrys = dexfile.entries();
class> clazz = null;
while (entrys.hasmoreelements())
//通過classloader載入得到差分包中的修復了的class
clazz = dexfile.loadclass(entry, patchclassloader);
if (clazz != null)
}} catch (ioexception e)
}
fixclass
看到下邊也許覺得奇怪,為什麼去獲取了乙個叫methodreplace的註解呢,這個註解是在**使用的,有什麼作用,
private void fixclass(class> clazz, classloader classloader) }}
解壓差分包我們可以看到andfix在發生錯誤的位置做了標記,就是這個註解
在錯誤的方法上新增註解,看上邊遍歷這個class檔案中所有的方法,找到這個註解呼叫replacemethod,故名思意,就是將錯誤的方法替換為正確的方法,有可能是存在多個class存在多個問題,其實andfix修復的原理就是解壓生成的patch.mf檔案,這個檔案中儲存了有錯誤的類的資訊,把這些類加入集合,遍歷集合通過上邊的方式獲取到註解,定位到錯誤的位置
private void replacemethod(classloader classloader, string clz,
string meth, method method)
if (clazz != null)
} catch (exception e)
}
public static void addreplacemethod(method src, method dest) catch (throwable e)
}
最後可以看到這裡已經是c層面的做法了
可以看到其實native層是通過指標修改方法的指向實現修復問題的,指向正確的修復之後的方法,就是這樣,ok了
《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具
檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...
原始碼閱讀 Glide原始碼閱讀之with方法(一)
前言 本篇基於4.8.0版本 原始碼閱讀 glide原始碼閱讀之with方法 一 原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 大多數情況下,我們使用glide 就一句 但是這一句 裡面蘊含著成噸的 with方法有以下幾個過載方法 publi...
原始碼閱讀 Glide原始碼閱讀之load方法(二)
原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 首先,load方法有以下幾個過載方法 public requestbuilder load nullable bitmap bitmap public requestbuilder load nu...