熱修復原理分析總結

熱修復概念

當應用出現bug的時候,可以幫助我們在不進行重新安裝應用的情況下實現對bug的修復的能力

熱修復流程步驟

在這裏插入圖片描述

常見熱修復解決方案


可以注意到Tinker和QZone 是通過類替換的方式來實現熱修復,而AndFix和Robust不是通過類替換的方式來實現的;
另外通過類替換的方式來實現熱修復的兩個框架Tinker和QZone,是不能即時生效的,必須重啓後生效

類替換方案

Qzone
原理:基於Multidex分包方案,將解決後的類打進一個單獨的dex補丁包,放入Elements數組的最前面,當ClassLoader查找類的時候,會按照順序遍歷Elements數組,理論上如果在不同dex中有相同的類,ClassLoader會優選選擇排在前面的dex文件中的類。
在這裏插入圖片描述

差分算法+類替換方案

Tinker
原理:運行的時候,啓動一個新進程(耗時),通過dexdiff算法計算對比bug.apk和fix.apk中dex的區別生成fix.dex補丁包,在運行時將bug.apk的dex與補丁包合成,重啓後通過ClassLoader加載合成後的dex,完成修復
在這裏插入圖片描述

native hook方案

AndFix
原理:在native層動態替換java層的方法,在native層將方法的成員一個一個的替換,由於是在動態的替換方法,所以不需要重啓,是即時生效的
缺點:

需要針對dalvik虛擬機和art虛擬機做適配,需要考慮指令集的兼容問題,需要native代碼支持,兼容性上會有一定的影響

查看下圖源碼片段,源碼中將方法中有bug的成員替換成了fix之後的成員,而且針對dllvik虛擬機和art虛擬機做了適配
在這裏插入圖片描述
Sophix
原理:在native層利用memcpy(des,src,sizeof(ArtMethod))直接替換有bug的方法,不用關心artMethod的具體實現,所以解決了兼容性問題。

字節碼插樁方案

Robust
原理:利用字節碼插樁,對每個函數在編譯打包階段自動插入了一段代碼,類似於代理,將方法執行的代碼重定向到其它方法中
流程:
在這裏插入圖片描述

public static ChangeQuickRedirect changeQuickRedirect;
//有問題的代碼
@Modify //改動代碼後手動添加註解用於補丁包的生成
public long getIndex() {
	return 100;
}

//經過插樁後實際執行的代碼
public long getIndex {
	if(changeQuickRedirect != null) {
			return 修復後的代碼;
	}
	return 100;
}

Robust爲每個class增加了個類型爲ChangeQuickRedirect的靜態成員,而在每個方法前都插入了使用changeQuickRedirect相關的邏輯,當 changeQuickRedirect不爲null時,可能會執行到accessDispatch從而替換掉之前老的邏輯,達到即時fix的目的。

總結

1.Tinker和QZone都是利用類替換的修復方式,區別是Tinker是利用差分算法生成記錄有修復前和修復後差分信息的dex,QZone是修復後的完整dex,一定程度上查分信息dex的大小是優於完整dex的。二者都是重啓後生效;
2.AndFix native層進行成員的替換,兼容性較差,已經不維護了,能即時生效
3.Robust 利用字節碼插樁,對每個函數在編譯打包階段自動插入了一段代碼,類似於代理;能即時生效

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章