1. 程式人生 > >安卓開發熱修復技術原理及選型

安卓開發熱修復技術原理及選型

到我寫這篇博文為止,現行的熱修復技術主要有四種:美團的Robust、qq空間的Nuwa,微信的Tinker,阿里百川HotFix,但是更確切的說應該是有三種,Tinker和HotFix,因為Tinker是基於Nuwa的,原理一樣,是它的進化版,我們到Github(https://github.com/jasonross/Nuwa )上可以看到,它已經一年沒有更新了。

美團的Robust(Github連結官方文件),雖然最近都在更新,但是還不夠完善,無法更新so\res等檔案,沒有形成系統的使用文件以及補丁包的管理,使用起來非常麻煩,所以在這裡我們將分別討論微信Tinker和阿里百川HotFix的原理及技術選型。

原理

一、Tinker

Tinker(官網連結) 是一個開源專案(Github連結),講到Tinker的原理我們要先說說Nuwa的原理,Nuwa實現熱修復的方案基於Android的dex分包基礎上,dex分包是為了解決方法數達到64K天花板問題,簡單來說就是將一個dex檔案拆分成多個dex檔案,在應用啟動時其中一個作為主dex進行載入,應用啟動後將會逐個載入其他dex,多個dex檔案會排列成一個有序的陣列,Dalvik虛擬機器載入類的過程中,會順序遍歷這些dex檔案,在每個dex檔案中查詢對應得類,如果找到就返回,沒有找到就繼續在下一個dex檔案中查詢。因此,理論上,如果多個dex檔案中存在相同的類,那麼排在陣列前面的dex檔案中的類將會被優選選擇。因此,Numa實現熱修復是將修復後的程式碼所在的dex插入到dex陣列的最前面使達到新類替換舊類的目的,讀者如果想深入瞭解可以看看這篇關於安卓載入類的過程的博文:

https://juejin.im/entry/57c3a2a3c4c9710061927b6c , 原理如下圖所示:

Nuwa實現原理.png

但是這種方案有一個缺點,由於新增加了dex,如果修復的類到了一定數量就會影響啟動效能特備是再ART模式下更容易導致補丁包異常大,針對這個不足,微信提出了Tinker方案,原理如下:

圖片.png

圖片.png

二、阿里百川HoxFix(Sophix)

官網連結 阿里的熱修復技術經歷了Dexposed --->AndFix --> HoxFix 1.x --> HoxFix2.0.1(Sophix)的演化, 從最初的只支援方法修復到現在可以實現全修復,並且支援所有安卓系統版本,穩定性和相容性、安全性都得到了大的提升,由於最新的Sophix沒有開源,我們只能從它的前身AndFix(

Github連結)去大概看看它的實現原理。AndFix只能修復方法,其參考了Hook的思想,跟Dexposed 相比做到了更好的系統相容性。

AndFix修復方法的原理.png

對於實現方法的替換,需要在Native層操作,經過三個步驟,實現過程如下圖所示:

圖片.png

阿里Hotfix2.X 類修復方案

Hotfix2.X在熱修復過程中是不侵入打包過程的,而是通過補丁工具生成補丁。由於熱部署Andfix修復正在執行的方法有Crash的風險, 所以補丁工具提供引數由業務方來決定是否嘗試走熱部署;如果使用者Patch的方法沒有被高頻呼叫同時又有實時生效的需求,那麼可以優先選擇走熱部署方案;但這並非絕對,當代碼變更導致熱部署不支援時,還是會轉向冷部署。

熱部署

熱部署不用重啟應用就能夠看到效果,就是AndFix支援的程式碼變更,此時走優化後的AndFix方案,也就是Hotfix1.X方案。

冷部署

冷部署需要重啟應用才能夠看到效果,就是AndFix不支援的程式碼變更。冷部署針對Davilk和Art分別做了不同的處理。

阿里Hotfix2.X SO檔案修復方案

Davilk和ART下SO檔案載入的方式不一樣,導致了需要區分Art和Davilk做不同的處理:

ART下預Load原來的SO檔案,再載入補丁SO檔案;

Davilk下預Load補丁SO檔案,再載入原來的SO檔案。

這裡的關鍵是:綜合機型支援的Abis和補丁包中的Abis共同決定補丁SO的新LibPath。這兩種載入方式都需要對載入兩次SO檔案,勢必會增加一次本地記憶體的消耗,因此為了達到更好的效能,在Hotfix2.X中提供了下面兩個介面替換掉系統載入SO檔案的介面:

SOPatchManager.load(String libPath) 代替     System.load(String pathName)

SOPatchManager.loadLibrary(String libName)代替     System.loadLibrary(String libName)

阿里Hotfix2.X 資原始檔修復方案

在資原始檔中,資源ID編碼於Resources.arsc檔案中,排布緊密,並按照排布順序進行自動編號;RES目錄儲存所有帶ID的資原始檔。佈局檔案為二進位制形式的XML檔案,XML以資源ID的方式引用其他資源;Assets目錄存放所有原始檔案,不帶ID;Aapt進行資源的構造,包括自動分配資源ID與R檔案的生成,預設情況下,每次編譯不保證和之前包中的ID一致。

目前市面上普遍採用的三種資源修復方案:

1、差量合成完整的資源包,執行時完整載入資源;這種方案的缺點是:合成資源佔用時間和記憶體,容易引起卡頓。 2、 修改aapt,對以後可能新增的資源提前留空,執行時Patch包中新增資源ID對應留出的位置;該方案的缺點是:需改變打包流程,修改程式碼並編譯替換SDK中的Aapt;打包侵入太強,且留空佔用一定磁碟空間。留空多少是預先定好的,無法改變。 3、外掛化,元件化資源;這種方式的缺點是:資源需要劃分模組,提前規劃。

百川資原始檔修復方案直接基於新舊兩個APK來構造補丁包,不需要改造AAPT,對編譯過程無要求;同時,精確比較各個資源ID的使用情況,最大程度利用原先基線包資源,補丁包中只包含新增和修改的資源;在執行時無需合成操作,快速應用生效,不影響效能

兩種熱修復技術對比(2017年3月29日為止最新)

專案 阿里Sophix 微信Thinker
類替換 yes yes
so替換 yes yes
資源替換 yes yes
全平臺支援 yes yes
補丁包大小 較小 較小
即時生效 yes(增刪方法採用冷啟動) no (重啟生效)
效能損耗 較小
侵入式打包 無侵入式打包 依賴侵入式打包
視覺化打補丁包 yes no
接入複雜度 簡單 相對複雜
安全性 加密傳輸及簽名校驗 、採用https請求 未知
應用加固 支援(用未加固的apk打補丁包) 未知
費用 免費 日請求量<1W免費,大於1W按級別收取不同費用

目前官網公佈的使用Sophix 的安卓應用,如下圖所示:

圖片.png

使用Tinker的應用目前只知道有微信,至於有沒有其它產品,由於官方沒有公佈,暫時不知道。

總結

個人對比: 1、對bug修復及時,大部分bug不需要重新啟動就可以立即看到效果; 2、接入的步驟比Tinker簡單,降低了學習成本; 3、比Tinker更低的效能損耗; 4、最重要的:免費,以後會不會收費就不知道了; 5、Thinker收費,意味著更好的服務,更穩定的效能; 6、目前截止到Sophix2.0.9版本為止,對res下的檔案bug修復易導致崩潰; 基於以上幾點,我建議大家選擇用Sophix 進行熱更新;

作者:android開發經驗總結 連結:https://www.jianshu.com/p/b9ed58405ded 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。