1. 程式人生 > >Android熱修復框架匯總整理(Hotfix)

Android熱修復框架匯總整理(Hotfix)

支付 業務開發 桌面 lib 業務 exce 修復技術 同進程 熱更新

??Android平臺出現了一些優秀的熱更新方案,主要可以分為兩類:一類是基於multidex的熱更新框架,包括Nuwa、Tinker等;另一類就是native hook方案,如阿裏開源的Andfix和Dexposed。

  • 基於native hook的方案

??需要針對dalvik虛擬機和art虛擬機做適配,需要考慮指令集的兼容問題,需要native代碼支持,兼容性上會有一定的影響;

  • 基於Multidex的方案

??需要反射更改DexElements,改變Dex的加載順序,這使得patch需要在下次啟動時才能生效,實時性就受到了影響,同時這種方案在android N [speed-profile]編譯模式下可能會有問題。

??從技術流派上來說,Android熱補丁技術應該分為以下兩個流派:

  • Native,代表有阿裏的Dexposed、AndFix與騰訊的內部方案KKFix(查不到);
  • Java,代表有Qzone的超級補丁、大眾點評的Nuwa、百度金融的RocooFix, 餓了麽的Amigo以及美團的Robust。

??相關技術文章

  • Android 熱修復專題:支付寶、淘寶、微信、QQ空間、餓了麽、美麗說蘑菇街、美團大眾點評方案集 https://zhuanlan.zhihu.com/p/25863920
    技術分享圖片

阿裏Dexposed -- native解決方案

原理:

  • 直接在native層進行方法的結構體信息對換,從而實現完美的方法新舊替換,從而實現熱修復功能

??他的思想完全來源於Xposed框架,完美詮釋了AOP編程,這裏用到最核心的知識點就是在native層獲取到指定方法的結構體,然後改變他的nativeFunc字段值,而這個值就是可以指定這個方法對應的native函數指針,所以先從Java層跳到native層,改變指定方法的nativeFunc值,然後在改變之後的函數中調用Java層的回調即可。實現了方法的攔截功能。

  • 基於開源框架Xposed實現,是一種AOP解決方案
  • 只Hook App本身的進程,不需要Root權限
    技術分享圖片

優點:

  • 即時生效
  • 不需要任何編譯器的插樁或者代碼改寫,對正常運行不引入任何性能開銷。這是AspectJ之類的框架沒法比擬的優勢;
  • 對所改寫方法的性能開銷也極低(微秒級),基本可以忽略不計;
  • 從工程的角度來看,熱補丁僅僅是牛刀小試,它真正的威力在於『線上調試』;
  • 基於Xposed原理實現的AOP不僅可以hook自己的代碼,還可以hook同進程的Android SDK代碼,這也就可以讓我們有能力在App中填上Google自己挖的坑。

缺點:

  • Dalvik上近乎完美,不支持ART(需要另外的實現方式),所以5.0以上不能用了;
  • 最大挑戰在於穩定性與兼容性,而且native異常排查難度更高;
  • 由於無法增加變量與類等限制,無法做到功能發布級別;

相關鏈接:

  • 文章:https://www.zhihu.com/question/31894163
  • 文章:
    http://www.wjdiankong.cn/android%E4%B8%AD%E5%85%8Droot%E5%AE%9E%E7%8E%B0hook%E7%9A%84dexposed%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0/
  • Dexposed源碼:https://github.com/alibaba/dexposed
  • Xposed源碼:https://github.com/rovo89/Xposed

阿裏AndFix -- native解決方案

原理:

  • 與Dexposed一樣都基於開源框架Xposed實現,是一種AOP解決方案

優點:

  • 即時生效
  • 支持dalvik和art(AndFix supports Android version from 2.3 to 7.0, both ARM and X86 architecture, both Dalvik and ART runtime, both 32bit and 64bit.)
  • 與Dexposed框架相比AndFix框架更加輕便好用,在進行熱修復的過程中更加方便了

缺點:

  • 面臨穩定性與兼容性問題
  • AndFix不支持新增方法,新增類,新增field等

相關鏈接:

  • 文章:https://zhuanlan.zhihu.com/p/23935568
  • AndFix源碼:https://github.com/alibaba/AndFix

QQ空間--Dex分包方案(大眾點評的Nuwa參考其實現並開源)

原理:

  • 原理是Hook了ClassLoader.pathList.dexElements[]。因為ClassLoader的findClass是通過遍歷dexElements[]中的dex來尋找類的。當然為了支持4.x的機型,需要打包的時候進行插樁。
  • 越靠前的Dex優先被系統使用,基於類級別的修復

技術分享圖片

技術分享圖片

優點:

  • 不需要考慮對dalvik虛擬機和art虛擬機做適配
  • 代碼是非侵入式的,對apk體積影響不大

缺點:

  • 需要下次啟動才會生效
  • 最大挑戰在於性能,即Dalvik平臺存在插樁導致的性能損耗,Art平臺由於地址偏移問題導致補丁包可能過大的問題
  • 虛擬機在安裝期間為類打上CLASS_ISPREVERIFIED標誌是為了提高性能的,我們強制防止類被打上標誌是否會影響性能?這裏我們會做一下更加詳細的性能測試.但是在大項目中拆分dex的問題已經比較嚴重,很多類都沒有被打上這個標誌。

相關鏈接:

  • 文章:https://zhuanlan.zhihu.com/magilu/20308548
  • 文章:http://blog.csdn.net/sbsujjbcy/article/details/50812674
  • Nuwa源碼:https://github.com/jasonross/Nuwa
  • HotFix源碼:https://github.com/dodola/HotFix
  • DroidFix源碼:https://github.com/bunnyblue/DroidFix

美團Robust -- Instant Run 熱插拔原理

原理:

  • Robust插件對每個產品代碼的每個函數都在編譯打包階段自動的插入了一段代碼,插入過程對業務開發是完全透明
  • 編譯打包階段自動為每個class都增加了一個類型為ChangeQuickRedirect的靜態成員,而在每個方法前都插入了使用changeQuickRedirect相關的邏輯,當 changeQuickRedirect不為null時,可能會執行到accessDispatch從而替換掉之前老的邏輯,達到fix的目的。

技術分享圖片

優點:

  • 幾乎不會影響性能(方法調用,冷啟動)
  • 支持Android2.3-8.x版本
  • 高兼容性(Robust只是在正常的使用DexClassLoader)、高穩定性,修復成功率高達99.9%
  • 補丁實時生效,不需要重新啟動
  • 支持方法級別的修復,包括靜態方法
  • 支持增加方法和類
  • 支持ProGuard的混淆、內聯、優化等操作

缺點:

  • 代碼是侵入式的,會在原有的類中加入相關代碼
  • so和資源的替換暫時不支持
  • 會增大apk的體積,平均一個函數會比原來增加17.47個字節,10萬個函數會增加1.67M。
  • 會增加少量方法數,使用了Robust插件後,原來能被ProGuard內聯的函數不能被內聯了

相關鏈接:

  • 美團技術文章:https://tech.meituan.com/android_robust.html
  • 美團技術文章:https://tech.meituan.com/android_autopatch.html
  • Robust源碼:https://github.com/Meituan-Dianping/Robust

微信Tinker

原理:

  • 服務端做dex差量,將差量包下發到客戶端,在ART模式的機型上本地跟原apk中的classes.dex做merge,merge成為一個新的merge.dex後將merge.dex插入pathClassLoader的dexElement,原理類同Q-Zone,為了實現差量包的最小化,Tinker自研了DexDiff/DexMerge算法。Tinker還支持資源和So包的更新,原理類同InstantRun

技術分享圖片

優點:

  • 支持動態下發代碼
  • 支持替換So庫以及資源

缺點:

  • 不能即時生效,需要下次啟動

微信已知問題:

  • Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大組件(1.9.0支持新增非export的Activity);
  • 由於Google Play的開發者條款限制,不建議在GP渠道動態更新代碼;
  • 在Android N上,補丁對應用啟動時間有輕微的影響;
  • 不支持部分三星android-21機型,加載補丁時會主動拋出"TinkerRuntimeException:checkDexInstall failed";
  • 對於資源替換,不支持修改remoteView。例如transition動畫,notification icon以及桌面圖標。

相關鏈接:

  • 文章:http://geek.csdn.net/news/detail/104000
  • Tinker源碼:https://github.com/Tencent/tinker

對比圖(來自不同的地方)

來自微信

技術分享圖片

來自蘑菇街 Android 熱修復探索之路

技術分享圖片

其他文章

淺談Android熱修復:

http://blog.csdn.net/caihongdao123/article/details/52051799

Android熱修復框架匯總整理(Hotfix)