APP 熱修復都懂了,你會 SDK 熱修復嗎?最全方案在這裏!

前言

剛開始要作 SDK 熱修復,我是拒絕的 ~面試

某日,解決完一個線上 bug 後,我冒出了一個念頭:讓咱們的 SDK 也具備熱修復的能力唄!算法

可是查了查,網上資料少、不少熱修復方案只針對app……api

但是我都拍胸脯向老大誇口了,焉有退縮的道理?!安全

加上萬一之後手抖,出了個什麼大 bug 或者兼容問題,個人職業生涯不就要終結了!?架構

我滴乖乖,保命要緊!仍是趕忙作個保底方案吧。app

1、背景和目的

咱們想實現的效果很簡單,以下場景三:框架

2、技術方案

先說明下,方案沒有最好,只有最合適。雖然我最終選定了方案四,但若是各位小夥伴的團隊有資源、有其餘方案的經驗、SDK的熱更需求更豐富,能夠自行選擇其餘方案。性能

方案一:JAR 替換

步驟

從服務端下載 jar -> 經過反射,加載jar -> 建立相關對象而且操做之。學習

方案參考:
Android SDK熱修復機制簡析以實現
優缺點

優勢:優化

無兼容問題

缺點:

一、反射消耗性能;

二、jar 包若是體積大,整個下載就很不友好;

三、肯定改動的代碼範圍繁瑣,維護麻煩。

方案一改進:子 JAR 替換

步驟

一、針對 jar 包體積大的狀況,咱們能夠考慮對 sdk 項目進行拆包(拆module),分紅小的 jar 包和主包

二、主包負責反射加載,若是須要熱修,下發子 jar 便可,比較輕量。

優缺點

優勢:

只下發子包,輕量

缺點:

一、比較適合主包變更小的狀況;

二、主包和子包耦合性強;

三、仍是須要用到反射。

方案二:插件化

步驟

將SDK分包,宿主包僅提供 API 和加載核心實現的插件包,插件包就能夠熱更了。

優缺點

優勢:

靈活

缺點:

對主項目工程的依賴太大,每每一些基本配置須要依賴於主工程的項目源碼;

使用接入成本高,配置麻煩,而 SDK 的業務接入方須要的是快速接入;

插件化框架可能會對系統原生代碼的運行形成不可預估的影響;

不得不依賴不少不須要的插件化框架功能。

方案三:業務方熱更

走投無路之下,我想起,誒!不少 app 熱更方案不是說支持 lib 熱更嗎!那先做爲一個保底方案吧。

步驟

經過業務方 app 熱更 lib 包。

優缺點

優勢:

熱更權把控在業務方手中,對業務方透明

缺點:

一、lib 包太大時,下載仍是很耗流量的

二、diff 算法沒法計算新舊 lib 的差別,只能整個替換掉

三、步驟至關繁瑣,以下圖:

方案四:改造現有 APP 熱修復方案

1. 那在選擇熱修復方案時考慮點有哪些?

1. 熱更項目的需求

  • 只須要簡單的方法級別 Bug 修復?
  • 須要資源及 so 庫的修復?
  • 須要 Native 的修復?
  • 對平臺兼容性要求及成功率要求?
  • 是否須要對補丁包進行管理?
  • 公司資源是否支持商業付費?

2. 學習及使用成本

  • 集成難度和複雜度
  • 代碼侵入性
  • 調試維護

3. 選擇框架的關注點

  • 儘可能大廠
  • 性能過關
  • 有專人維護
  • 熱度高,開源社區活躍

2. 總結出須要熱更的 SDK 特色

  1. 主要是代碼熱更,無so庫、資源更新需求;
  2. 實時性要求高,由於一旦出問題,對業務方的影響極大;
  3. 兼容性要求高,你沒法預料到業務方的活躍用戶都有啥機型。

3. 那咱們趕忙來看下,現有的 APP 熱修復方案都有哪些?

3.1 綜合優化的產物 —— Sophix(棄)

Sophix 功能完善、開發簡單透明,惋惜沒開源,沒法改造。

3.2 底層替換方案(棄)

底層替換方案不可避免地存在兼容問題,棄之。

3.3 類加載方案 —— Tinker

優勢:

一、用戶多

二、更新時間新,相比之下,其餘有在Github上開源的框架,star數都是7000如下,上次更新時間都在1年前,甚至2年前。

缺點:

一、dex合成佔用ROM較大

二、不夠實時

三、須要改造Application,業務方有感知。(也能夠參考 InstantRun 作到不修改 Application 達到替換 Application 的效果,但該方案大量 hook 系統 api,不夠穩定,大概有 1/1w 的機率會出現替換失敗,因此Tinker最終仍是沒有使用InstantRun的方式)

還有兩個問題,留給你們去思考:

一、會不會影響業務方加固?

二、和業務方是否衝突?

  • 方案參考:
    基於Tinker的SDK全局熱更新方案(全網惟一)
  • 擴展:
    InstantRun 如何動態替換 Application,總結起來就兩步:
  1. 打包時替換 Application 標籤,插入BootstrapApplication
  2. 運行時 hook 系統api,將 BootstrapApplication 換回 MyApplication
3.4 插樁 —— 美團 Robust

Robust 的原理能夠簡單描述爲:

一、打基礎包時插樁,在每一個方法前插入一段 if(changeQuickRedirect==null)-else 的邏輯;

二、加載補丁時,從補丁包中讀取要替換的類及具體替換的方法實現,新建 ClassLoader 加載補丁 dex,當目標方法被執行時,此時 changeQuickRedirect != null,方法邏輯流程被改變,而替換掉以前的舊邏輯,達到 fix 的目的。

優勢:

  1. 兼容性最優,兼容加固
  2. 實時生效
  3. 粒度細,支持方法級別的修復
  4. 高穩定性,修復成功率高達99.9%

缺點:

  1. 在編譯階段插件侵入了產品代碼,對運行效率、方法數、包體積仍是產生了一些反作用。(支持指定某些class無需插入)
  2. so和資源的替換目前暫未實現
  3. 沒法新增變量
  4. 沒有補丁管理和安全校驗,須要開發者自行實現

思考:

1. 和其餘的插樁插件混用是否有衝突?

3、實現

就在我美滋滋地接入 Robust 時,問題來了!

Robust 須要是 Application 才能插樁和打補丁,要用在 SDK 上,仍是須要一輪改造的。

如何改造?我將在下篇博文中詳解,同時將推出封裝好的庫,讓 SDK 開發者只需 5 分鐘便可讓本身的 SDK 擁有熱修復的能力,敬請期待。

4、除了熱更技術自己,咱們還應該關心的

固然,咱們的焦點並不侷限在技術實現上,還有不少值得咱們去考慮的:

咱們怎麼對分發進行控制?對監控數據進行統計?若是補丁引發了崩潰,咱們怎麼第一時間補救?

1. 精準分發

結合外部維度系統,根據用戶維度,好比渠道、系統版本等等作有差異的下發。

2. 數據分析

上線後咱們最關心的就是補丁的兼容性和成功率。

  1. 補丁拉取成功率 = 請求補丁成功的用戶 / 發起請求補丁的用戶
  2. 補丁下載成功率 = 下載補丁成功的用戶 / 嘗試下載補丁的用戶
  3. patch應用成功率 = patch成功的用戶 - 回滾的用戶 / 補丁下載成功的用戶

3. 補丁回滾機制

咱們須要支持自動監控崩潰,若是是下發的補丁引發的,則下次啓動補丁自動失效,避免擴大影響範圍。

Android開發資料+面試架構資料 免費分享 點擊連接 便可領取

《Android架構師必備學習資源免費領取(架構視頻+面試專題文檔+學習筆記)》

相關文章
相關標籤/搜索