安卓開發熱修復技術原理及選型
到我寫這篇博文為止,現行的熱修復技術主要有四種:美團的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陣列的最前面使達到新類替換舊類的目的,讀者如果想深入瞭解可以看看這篇關於安卓載入類的過程的博文:
Nuwa實現原理.png
但是這種方案有一個缺點,由於新增加了dex,如果修復的類到了一定數量就會影響啟動效能特備是再ART模式下更容易導致補丁包異常大,針對這個不足,微信提出了Tinker方案,原理如下:
圖片.png
圖片.png
二、阿里百川HoxFix(Sophix)
官網連結
阿里的熱修復技術經歷了Dexposed --->AndFix --> HoxFix 1.x --> HoxFix2.0.1(Sophix)的演化,
從最初的只支援方法修復到現在可以實現全修復,並且支援所有安卓系統版本,穩定性和相容性、安全性都得到了大的提升,由於最新的Sophix沒有開源,我們只能從它的前身AndFix(
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 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。