Android 熱修復原理(主要談程式碼修復)
Android開發中,熱修復技術被越來越多的開發者使用,市面上也出現很多成熟的開源框架。但對大部分開發者來說,熱修復依然是一個既熟悉又陌生的詞。僅僅知道熱修復的作用,會使用框架,那樣意義並不大。我們還要知道熱修復的原理,這樣不管框架如何變化,只要基本原理不變,我們都可以快速掌握它,或者自己動手寫一個適合專案的熱修復框架。
熱修復介紹
1.開發流程

開發流程對比
當專案出現緊急bug時,傳統的開發流程是釋出新版本,引導使用者覆蓋安裝。拋開平臺稽核上線的時間不說,一天重複下載安裝至少兩次的使用者體驗是很差的。而熱修復的出現完美解決了這個問題,使用者在收到伺服器推送過來的修復包後,在專案執行時進行修復。整個過程是在使用者無感知狀態下完成,也無需下載相對來說較大的安裝包,代價小。
總結為兩個優點:
- 無需重新發版,修復效率高
- 使用者無感知,代價小
2.都能修復什麼
- 資源修復
- 程式碼修復
- so庫修復
3.程式碼修復技術分類
目前最主要有三種方案:
- 基於類載入與 Dex 分包方案,進行 Dex 插樁/替換
- Native Hook 進行底層替換
- Install Run 進行類的注入
由於國內手機廠商定製系統的多樣,Dex 插樁/替換是我認為最適合的方案。
Dex插樁原理
ClassLoader 是通過呼叫 findClass 方法,在 pathList 物件中的 dexElements[] 中遍歷dex檔案尋找相關的類。由於靠前的dex會優先被系統呼叫,所以就有了插樁的概念。將修復好的 dex 插入到 dexElements[] 的最前方,這樣系統就會呼叫修復好的插入類而不是靠後的 bug 類。

Dex插樁原理圖
上圖中,patch.dex 是插入的 dex ,classes2.dex 是原有的 bug dex。ClassLoader 在遍歷時優先獲取了 patch.dex 中的 D.class ,所以 classes2.dex 中的 D.class 就不會被呼叫,這樣就完成了對 D.class 的替換,修復了bug。
本文簡單介紹了程式碼修復的技術原理,下篇文章將從系統原始碼入手,結合我自己封裝的程式碼修復開源框架Fettler,詳細解讀程式碼修復的每一個過程。本文如果有出現錯誤的地方也請幫忙在評論區指出,共同學習進步,謝謝大家。