1. 程式人生 > >深入探索Android熱修復技術原理讀書筆記——第一章:熱修復技術介紹

深入探索Android熱修復技術原理讀書筆記——第一章:熱修復技術介紹

第一章 熱修復技術介紹

1.1 什麼是熱修復

傳統開發流程:

  • 重寫釋出版本代價太高
  • 使用者下載安裝成本太高
  • bug修復不及時,使用者體驗差

有許多開發者找到了合適的解決辦法,比如:

  • 經常變更的業務用H5獨立出來,但是增加了學習成本,並且無法轉為H5的程式碼還是無法修復
  • 用外掛化的方案,但是學習外掛化工具需要的成本也高,對老程式碼的改造也不是短時間就能完成的

熱修復技術:

  • 無需重新發版,實時高效熱修復
  • 使用者無感知修復,無需下載新的應用,代價小
  • 修復成功率高,把損失降到最低

1.2 技術沉澱

阿里系:

  • Dexposed:基於Xposed改進,針對Android Dalvik虛擬機器執行的Java Method Hook技術,但無法相容Android5.0以後的虛擬機器
  • Andfix:也是一種底層替換的方案,做到了Dalvik和ART的相容
  • Hotfix:結合實際工程中的使用Andfix的經驗,推出阿里百川Hotfix,但只提供了程式碼層面的修復,對於資源和so的修復還未實現
  • Sophix:2017年6月推出Sophix,打破了各家紛爭的局面,在程式碼修復,資源修復,so修復方面,都做到了業界領先

其他著名的熱修復,但是各自有各自的侷限性,補丁過大,效率低下,不夠穩定,用起來繁瑣:

  • 騰訊QQ空間的超級補丁
  • 微信的Tinker
  • 餓了麼的Amigo
  • 美團的Robust

1.3 詳細比較

Sophix和Tinker與Amigo的比較:

各項指標都佔優,唯一不支援的就是四大元件的修復

1.4 技術概覽

1.4.1 設計理念

Sophix的設計理念,就是非侵入性

  • 最終的實現只有兩個生成的新舊apk,唯一要做的就是初始化和請求補丁兩行程式碼
  • 不會侵入apk的build流程中
  • 不改變任何打包元件
  • 不插入任何AOP程式碼

1.4.2 程式碼修復

兩大方案:

  • 阿里系的底層替換,限制很多,但時效性好,載入輕快,立即見效
  • 騰訊系的類載入,需要重新冷啟動才能生效,但修復範圍廣,限制少

底層替換方案:

  • 在原有類的基礎上進行修改,無法對原有類的方法和欄位進行增減,方法數的變化伴隨著方法索引的變化,這樣在訪問方法的時候就無法正常地索引到正確的方法了,因為增減會導致無法索引到正確的方法和欄位
  • 更為嚴重的就是,比如程式正在執行中,突然某個類加了一個欄位,那有可能在之前已經產生了這個類的一箇舊的例項,那麼新方法用到這個舊的例項物件,去訪問新的欄位,那麼會產生不可預期的結果
  • 最最令人詬病的是底層替換的不穩定性,傳統的底層替換方式,都是去直接依賴修改虛擬機器方法實體的具體欄位,比如,改Dalvik方法的jni函式指標、改類或方法的訪問許可權等,這有一個很嚴重的問題,由於Android的碎片化,是開源的,不同的手機廠商可能會對這個ArtMethod結構體進行了修改,那麼在這些修改過原始碼的裝置上,通用性的替換機制就會出問題。這是不穩定的根源
  • 只要保證ArtMethod陣列仍是以線性結構排列,就能直接使用於將來的Android8.0,9.0等新版本

類載入方案:

  • 在app重新啟動後讓Classloader去載入新的類,因為在app執行到一半的時候,所有需要發生變更的類已經被載入過了,只有在下次重啟的時候,還沒走到業務邏輯之前搶先載入補丁中的新類
  • QQ空間方案會侵入打包流程、QFix的方案需要獲取底層虛擬機器的函式,不夠穩定可靠,並且無法新增public函式、微信的Tinker方法是完整的全量dex載入,可以很大的節省空間,但是效能消耗比較嚴重,因此,Tinker方案的時空代價轉換的價效比並不高
  • 阿里採用的也是全量合成dex的技術,直接利用Android原先的類查詢和合成機制,快速合成新的全量dex,這樣既不需要處理合成時方法數超過的情況,對於dex的機構也不用進行破壞性重構。重新編排了包中的dex的順序,大大減少合成補丁的開銷

雙劍合璧:

  • Sophix的程式碼修復體系正是同事涵蓋了這兩種方案,兩種方案的結合,實現優勢互補,完全兼顧的作用
  • 在補丁生成階段,會根據實際程式碼變動情況進行自動選擇,小修改,在底層替換方案的限制內,直接用底層替換方案修復,這樣還可以做到程式碼修復即生效,對於超出底層替換限制的,就使用類載入替換,另外,執行時階段,Sophix還會判斷所執行的機型是否支援底層替換,不支援就走類載入修復,達到更好的相容性

1.4.3 資源修復

目前市面上的很多資源熱修復方案基本上都是參考了Instant Run的實現

Instant Run中的資源熱修復分為兩步:

  1. 構造一個新的AssetManager,並通過反射呼叫addAssetPath,把這個完整的新資源包加入到AssetManager中,這樣就得到了一個含有所有新資源的AssetManager。
  2. 找到所有之前引用到原有AssetManager的地方,通過反射,把引用處替換為AssetManager

阿里的方案:構造了一個package id為0x66的資源包,這個包裡只包含了改變了的資源項,然後在原有的AssetManager中addAssetPath這個包就可以了。補丁包裡面的資源,只包含原有包裡面沒有新的包裡面有的新增資源,以及原有內容發生了改變的資源。採用了更加優雅的替代方式,直接在原有的AssetManager物件上進行析構和重構,這樣所有原先對AssetManager物件的引用是沒有發生改變的,所以就不需要像Instant Run那樣進行繁瑣的修改了

阿里資源修復方案的優勢在於:

  1. 不修改AssetManager的引用處,替換更快更完全
  2. 不必下發完整包,補丁包中只包含有變動的資源
  3. 不需要再執行時合成完整包。不佔用執行時計算和記憶體資源

1.4.4 SO庫修復

SO庫修復本質上是對native方法的修復和替換

阿里採用的是類似類修復反射注入方式,把補丁so庫的路徑插入到nativeLibraryDirectories陣列的最前面,達到載入so庫的時候是補丁so庫,而不是原來so庫的目錄,從而達到修復目的。

1.5 本章小結

本章介紹了熱修復技術的主要使用場景和為業界帶來的變化,詳細說明了阿里巴巴推出的熱修復解決方案Sophix的由來,以及和其他各大主流方案進行了比較

總結

這章是本書的第一章,不過讀起來還是蠻受用的,大體瞭解了現在熱修復技術趨勢和藥店,內容大都是概念性的,有一部分地方肯定不可能看看簡述就能明白的,那麼需要在接下來的幾章內容好好來探索一番,覺得這本書真的挺不錯的!