Android熱修複技術原理詳解(最新最全版本)

来源:https://www.cnblogs.com/popfisher/archive/2018/03/11/8543973.html
-Advertisement-
Play Games

通過閱讀本文,你會對熱修複技術有更深的認知,本文會列出各類框架的優缺點以及技術原理,文章末尾簡單描述一下Tinker的框架結構。本文框架: 1. 什麼是熱修複? 2. 熱修複框架分類 3. 技術原理及特點 4. Tinker框架解析 5. 各框架對比圖。 ...


本文框架

  • 什麼是熱修複?
  • 熱修複框架分類
  • 技術原理及特點
  • Tinker框架解析
  • 各框架對比圖
  • 總結

  通過閱讀本文,你會對熱修複技術有更深的認知,本文會列出各類框架的優缺點以及技術原理,文章末尾簡單描述一下Tinker的框架結構。

一、什麼是熱修複?

正常開發流程

熱修複開發流程

熱修複優勢

修複什麼?

二、熱修複框架分類

現狀:百花齊放百家爭鳴

簡單分類

更合理的分類

三、技術原理及特點

3.1 阿裡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異常排查難度更高;
  • 由於無法增加變數與類等限制,無法做到功能發佈級別;

相關鏈接:

3.2 阿裡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等

AndFix(Dexpsed)框架不穩定的原因(痛點)

相關鏈接:

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

原理:

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

優點:

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

缺點:

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

插樁方案性能上的痛點:

相關鏈接:

3.4 美團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內聯的函數不能被內聯了

相關鏈接:

3.5 微信Tinker

原理:

  • 服務端做dex差量,將差量包下發到客戶端,在ART模式的機型上本地跟原apk中的classes.dex做merge,merge成為一個新的merge.dex後將merge.dex插入pathClassLoader的dexElement,原理類同Q-Zone,為了實現差量包的最小化,Tinker自研了DexDiff/DexMerge演算法。Tinker還支持資源和So包的更新,So補丁包使用BsDiff來生成,資源補丁包直接使用文件md5對比來生成,針對資源比較大的(預設大於100KB屬於大文件)會使用BsDiff來對文件生成差量補丁。


優點:

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

缺點:

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

Tinker已知問題:

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

Tinker性能痛點:

  • Dex合併記憶體消耗在vm head上,容易OOM,最後導致合併失敗。
  • 如果本身app占用記憶體已經比較高,可能容易導致app本系統殺掉。

相關鏈接:

3.6 阿裡Sophix

原理(雙劍合璧):

優化Andfix(突破底層結構差異,解決穩定性問題):


Andfix底層ArtMethod結構時採用內部變數一一替換,倒是這個各個廠商是會修改的,所以相容性不好。

Sophix改變了一下思路,採用整體替換方法結構,忽略底層實現,從而解決相容穩定性問題。

突破QQ和Tinker的缺陷


QQ和Tinker的缺陷

Sophix對dex的解決方案

  • Dalvik下採用阿裡自研的全量dex方案:不是考慮把補丁包的dex插到所有dex前面(dex插樁),而是想辦法在原理的dex中刪除(只是刪除了類的定義)補丁dex中存在的類,這樣讓系統查找類的時候在原來的dex中找不到,那麼只有補丁中的dex載入到系統中,系統自然就會從補丁包中找到對應的類。
  • Art下本質上虛擬機以及支持多dex的載入,Sophix的做法僅僅是把補丁dex作為主dex(classes.dex)而已,相當於重新組織了所有的dex文件:把補丁包的dex改名為classes.dex,以前apk的所有dex依次改為classes2.dex、classes3.dex ... classesx.dex,如下圖所示。

資源修複另闢蹊徑


常用方案(Instant Run技術):這種方案的相容問題在於替換AssetManager的地方

Sophix資源修複方案

SO修複另闢蹊徑


四、Tinker框架解析

  之所以只貼了Tinker的代碼框架,是因為目前開源的方案中是最好的,當然除了Robust。

代碼結構

修複流程

這裡後續再補一個詳細的源碼分析,敬請期待

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

來自Tinker的對比

來自Sophix的對比

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

其他文章

淺談Android熱修複:

六、總結

  如果不考慮增大apk的體積,只是簡單的修複代碼,不修複so和資源,選擇Robust是最穩定的,否則的話選擇Tinker是一個不錯的方案。雖然阿裡Sophix橫空出世,但是它不開源,而且商業收費,所以一般不是很賺錢的app選擇收費的可能就很小了。不過它確實各方面都做了大量的優化,本文中的很多知識點也來源於阿裡的《Android熱修複技術原理.pdf》一書,本書值得一讀,裡面就是基於Sophix框架來編排的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 【展示效果說明】 對 app 操作錄屏時,展示出手指在 app 上的觸摸效果可以看到具體點擊,感覺這樣比較方便,也不用做視頻後期了。 這裡簡單用 runtime 實現了一個這樣的效果,不需要修改任何代碼,只要將 UIWindow+Touch.m 分類導入工程即可。 展示效果如下: 【實現思路】 1. ...
  • 異常: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object 這是在intent發送數據的時候出現的,原因:通過intent傳遞的類實現了serialzable介面,但是那 ...
  • 恢復內容開始 打開monitor時出現 打開log一看,媽的,全是報錯日誌 真是聞者傷心,見者落淚。 隨便摘錄一篇日誌: 那麼長???!!!沒法看了,直接上網搜索。 第一種方法:據說是從外網stackoverflow流傳過來的秘方:只要用管理員身份打開就可以解決了。 實踐之後:完全不頂用啊!!! 第 ...
  • 最近在項目中需要做自動定位功能,就是你在參加會議通過掃描二維碼簽到的時候自動定位並將你的定位信息在簽到中上傳,這樣可以避免我們進行假簽到。在這個功能中,主要用到的是系統自帶的定位模塊,首先我們是需要配置定位功能的參數,然後當我們定位成功時調用特定的方法進行相應操作就可以了,當然,在定位失敗時我們也可 ...
  • 使用的自定義類,如下: 動態變數控制 動態添加方法 動態交換兩個方法的實現 攔截並替換方法 在方法上增加額外功能 對runtime進行歸納總結,代碼如下: 1、載入運行時頭文件: 2、具體實現代碼: ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,將全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...