全網獨家盤點Android熱修復方案(含阿里巴巴、美團、騰訊等)


上一個大的系列文章叫 “手把手講解”, 歷時10個月,出產博文二十余篇,講解細致,幾乎每一篇都提供了詳實的原理講解,提供了可運行 githubDemo,並且針對Demo中的關鍵地方進行了重點拆解。相信每一位詳細閱讀文章的同行都會有所收獲。但是,講解雖詳細,但是缺乏對於技術的深度的挖掘。

從今天開始開辟新的專題: 移動架構師專業技能深入淺出,以一步步成為架構師為目標,詳述一項架構師技能的最直接使用價值,橫向周邊知識以及縱深專業技術.

最直接使用價值: 網上最怕看到一種文章,全文開篇高大上,讓人覺得遙不可及,通篇看下來卻沒有展示技術如何落地,落地之后是何種效果。文章寫出來,就要以最容易讓人接受的方式帶讀者進入作者的世界,而不是裝作一副高高在上的樣子俯視眾生。所以,文章開篇,一定是最直接的展示技術的落地效果。提供可運行Demo可以讓讀者親自嘗試。

橫向周邊知識: 一項核心技術,必然不是獨立存在,技術是一個體系,但是一篇文章能夠詳述的技術有限,必然是以一項技術為中心,其他技術作為輔助。核心技術需要詳述,但是周邊技術,也需要交代,參天大樹拔地而起也少不得土壤作為依附。用簡明的語言交代周邊知識,並提供這些知識正確的研究方向。也是一個負責任的博文作者不可忽視的一步。

縱深專業技術: 做技術,最忌諱的就是淺嘗輒止。稍微深入一點就退出去,一來不利於理解底層實現,長此以往永遠只是一個技術小白,成不了大師;二來不利於長久記憶, 記憶力再強的人時間長了,技術細節必然會記憶模糊。但是如果深入內核,理解了原理,在技術的大方向上絕對不會偏差。作為要成為架構師的男人,即使記不了那么多細節,但是對於大方向的把握絕對不能錯。所以,技術縱深很有必要。

前情提要

上一篇 Android Muitldex熱更新修復方案原理提到了 熱修復的其中一種Muitidex方案,並且給出了演示Demo。但是真正完整去展現現實中的 熱修復開源框架,遠遠不夠。

正文大綱

  • 阿里AndFix 方案

  • 美團 Robust方案

  • 騰訊 Tinker dexdiff / DexMerge方案

  • 騰訊 QZone Muitidex方案

正文

熱修復方案按照是否必須重啟 分為兩類: 重啟生效 / 即時生效。按照 實現方式可以分為3類: java層的實現 / native層的實現 / java native混合實現

阿里AndFix 方案(已棄用)

AndFix 是 無需重啟 的 native層 的實現. 但是,AndFix目前已經3年多沒維護更新。因為阿里已經有了新的替代方案,不再需要維護。另外,這種純native的實現方式,兼容性十分堪憂。既然已經被棄用,但是稍微了解一下 實現方案也是沒問題的。

上圖解讀:圖中有一段程序按照 A=>B=>C的順序去執行,然而發現執行到B的時候,存在一個bug,AndFix的修復方式為:在native層執行到B方法的時候,把方法的指針指向了 補丁包里的B方法,繞過了原來的B方法。從而達到了修復bug的目的。

使用方法:

在需要修復的方法上面,加上@MethodReplace注解,給定參數,class和method,表示 該方法替換為 哪個類的哪個方法。

缺陷:修復粒度為:method. AndFix只能以方法為粒度去修復bug。作用有限,針對大范圍的類替換和資源替換,那就無能為力了。

美團 Robust方案

Robust 是 即時生效的Java層實現的熱修復實現方案.

美團的Robust方案,是參考了谷歌的InstantRun方案(之前在androidStudio里面有這個選項,可以選擇打開instant run運行app)的思路而設計出來的。

其主要設計思想就是一句話:編譯打包時,在程序的某些方法里面,都插入一段代碼(全自動操作):

當 changeQuickRedirect不為空的時候,該方法就會命中 if(changeQuickRedirect!=null),從而執行修復的實現代碼。當為空的時候,則正常執行原邏輯。

而平時我們自己編碼,只需要加上一個 @modify注解,來標記這個方法需要打補丁包,也就是需要插入上面這個 if(changeQuickRedirect!=null)代碼段。 

為什么它可以即時生效?

上圖解析:利用ClassLoader,當客戶端手機收到補丁包 patch.dex的時候,執行補丁包,把指定方法的 changeQuickRedirect用反射的手段賦值,讓它變成非空。從而讓下一次程序邏輯走到這里的時候,走修復之后的邏輯。

Robust是如何將這么多 ****if(changeQuickRedirect!=null)代碼段插入到代碼邏輯中的?:

上圖中的 if(changeQuickRedirect!=null)代碼段,並非我們手動編寫,而是由Robust框架自動插入的。這個技術叫做 字節碼插樁,意為:對class進行操作,按照class文件的格式,插入自己想要的邏輯。目前Robust支持兩種字節碼插樁方案 AspectJ 和 Javasist.

騰訊 Tinker dexdiff / DexMerge方案

Tinker 是騰訊自研的 重啟生效的 Java層的實現.

原理

Tinker基於一個基准dex,以及修復bug之后的dex,使用dexdiff算法,計算出差分包dex。然后把差分包推送給客戶端,客戶端收到之后,重啟運行app,把差分包dex和原dex進行合並,形成新的dex。然后ClassLoader去創建類class對象的時候,就會創建修復bug之后的類class對象。從而達到 修復bug的目的。 

Dexdiff算法

了解增量更新的人應該知道 bsdiff。bsdiff是無視文件格式,生成兩個二進制文件的差異文件。dexdiff是基於bsdiff,並且進行了針對dex文件格式的優化。Tinker除了支持Dex修復之外,還支持so修復,只不過so的差分包,是直接使用的bsdiff算法生成的。

騰訊 QZone Muitidex方案

Multidex方案是 基於ClassLoader的 純java實現 的 重啟生效的熱修復方案.

原理

Apk打包的時候可能生成多個classes.dex文件。JVM中 類加載器ClassLoader,在程序運行使用到某一個Class的時候,是按照順序查找的方式進行的。一旦找到,就會緩存起來,下一次loadClass就不會去查找,而是直接使用緩存中的(所以Muitldex方案必須重啟app). 而,當我們把補丁dex文件放到 順序查找的最前面,那么類加載器 查找到它之后,就會直接使用。原來的同樣的類便處於后方,不會再生效。由此,使用補丁Class完全替換了 原class.

至於更深入的原理,上一篇 Android Muitldex熱更新修復方案原理已經給出了詳細講解。在此就不贅述。

方案對比

題外話

隨着互聯網企業的不斷發展,產品項目中的模塊越來越多,用戶體驗要求也越來越高,想實現小步快跑、快速迭代的目的越來越難,還有65535,應用之間的互相調用等等問題,插件化技術應用而生。如果沒有插件化技術,美團、淘寶這些集成了大量“app”的應用,可能會有幾個g那么大。

所以,當今的Android移動開發,不會熱修復、插件化、組件化,80%以上的面試都過不了。

本人從網上搜集到了阿里P8大佬花了將近半個月時間將Android熱修復框架、插件化框架、組件化框架、圖片加載框架、網絡訪問框架、RxJava響應式編程框架、IOC依賴注入框架、最近架構組件Jetpack等等Android第三方開源框架整合成了一套系統知識筆記PDF,長達1042頁!相信看完這份文檔,你將會對這些Android第三方框架有着更深入、更系統的理解。

由於文檔內容過多,為了避免影響到大家的閱讀體驗,在此只以截圖展示部分內容,1042詳細完整版的【Android設計思想解讀開源框架】文檔領取方式:點贊+關注,然后私信關鍵詞 【1】即可獲得免費領取方式!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM