Android熱修復簡單總結

蕭霧宇發表於2019-02-18

1. Dex修復

Dex修復分為熱部署底層熱替換與冷部署重啟

1.1 熱部署底層替換

直接在native虛擬機器層替換原有方法,是在原來類的基礎上進行修改。

  1. AndFix:將native虛擬機器層原有的Method結構的所有成員變數替換成新函式Method結構的成員。

  2. Sophix:將native虛擬機器層原有的Method結構整體進行替換。

不適用的情況:

  1. 引起原有類中發生結構變化的修改
  2. 修復的非靜態方法會被反射呼叫

1.2 冷部署重啟

DexClassLoader -> DexPathList -> DexFile -> -> Element ->
dexElements.add(element)

當類的所有方法直接引用到的類(第一層級關係)和該類在同一個dex檔案中時,類校驗dvmVerifyClass就會返回true,類的accessFlags在虛擬機器層會被設定CLASS_PREVERIFIED已校驗標誌。

如果類沒被設定CLASS_PREVERIFIED,那麼類的Verify操作都將在類的初始化進行。而類的Verify僅僅是在apk第一次安裝執行dexopt的時候進行,但類的Verify會對類所有方法的指令都進行校驗,是個稍重的過程,當載入的類多的時,整個Dex的載入過程耗時較大,所以插樁給類載入效率帶來較大的影響。

2. 資源修復

2.1 Instant Run

  1. 構造載入了補丁資源的新AssetManager替換原有的AssetManager
  2. 將原有程式碼中所有引用到舊AssetManager的地方修改為新AssetManager

2.2 Sophix

構造一個package id不為0x7f的補丁資源包,此包只包含原有包中發生改變的資源以及新增的資源,然後在原有AssetManager的基礎上,反射呼叫addAssetPath方法將補丁資源寶載入進去。

3. SO庫修復

3.1 SO實時生效

1.Dalvik虛擬機器下動態註冊的native方法需實時修復,必須對so檔案改名
2.靜態註冊的native方法的實時修復,因為無法得知so庫中哪些native方法發生了變更,很難做到修復
3.對於新增動態註冊的native方法,需在dex中增加相應的Java方法,否則載入so檔案時報NoSuchMethodError,而增加Java方法是無法做到實時生效熱修復,所以so庫新增動態註冊的native方法也無法做到實時生效熱修復

3.2 SO冷部署重啟生效

1. 通常的冷啟動

SoFixRelaceCall.png
SoFixRelaceCall.png

用自己實現的載入SO庫的介面替換System預設的載入SO庫的介面。

2. Sophix的冷啟動

SoFixInject.png
SoFixInject.png

反射注入方式將補丁SO插入到nativeLibraryDirectories/nativeLibraryPathElements陣列的最前面,達到優先載入補丁SO的目的,從而實現SO修復。

相關文章