爲了解決 Native 模塊上線後的問題,mPaaS 提供了熱修復功能,實現不發佈客戶端 apk 場景下的熱修復。目前 Android 端熱修復主要包括 andfix 和 dexpatch,考慮到 andfix 的版本兼容性,目前主要推薦使用 DexPatch。android
DexPatch 修復原理比較簡單,就是在啓動後經過 RPC 拉取當前須要下發的 jar 包地址,而後經過獨立進程去下載 jar 包文件,下載完成後保存。在二次啓動的時候 hook 系統的 classLoader,修改 DexPathList,在其數組的最前面加入一個有修改過的 class 的 dex 文件,使其攔截住數組後面的 dex 文件中同名的 class 的加載。apache
以下圖所示,classloader 就會優先加載 Patch.dex 中的 Ding.class,而忽略 Classes.dex 中的 Ding.class,達到了替換的效果。 數組
基於這樣的原理,DexPatch 具備如下特徵:框架
如下是關於在 mPaaS 下使用 DexPatch 模塊的主要步驟以及問題排查思路,方便開發者平常開發。less
啓動階段調用 MPHotpatch.init(),主要觸發 Patch 信息的 RPC 請求,若是命中發佈 Patch 發佈規則,RPC 會返回 Patch 的 jar 包下載地址,客戶端去觸發下載,下載後保存在客戶端私有目錄/data/user/0/
包名/dexpatch/patch/
下。ide
以組件化模式接入爲例,介紹下 Patch 發佈的主要流程。工具
(1)代碼改動前組件化
須要保存改動前的構建產物,方便後續作 Patch 生成,地址在:build/intermediates/bundle/xxxx-raw.jar
gradle
(2)代碼改動後ui
從新編譯,保存構建產物,產物地址:build/intermediates/bundle/xxxx-raw.jar
(3)生成白名單配置
主要用於熱修復包時用於指定修復的類,配置文件爲 .txt 格式,該配置文件應包含並按順序包含如下信息:
須要 Patch 的類。以 L 開頭,後跟以混淆後真實類名。若是多個類,每行只可寫一個。示例:Lxxx.xxx.clazzX
設置 Patch 類型爲 dexpatch。示例:PatchType: dexpatch
設置是不是靜態 Bundle。默認爲 false,若是是靜態連接的 Bundle,須要顯式設置爲 true。示例:HostDex: true
(*目前 mPaaS 客戶端的模塊通常都在靜態連接裏,通常寫 true)
(4)查看簽名
生成 patch 須要用到項目的打包祕鑰,須要提早準備好,能夠在打包腳步下找到對應的配置
(5)生成 patch
① 經過 mPaaS 自帶的 IDE 工具,點擊熱修復,進入修復頁面。
② 按照頁面提示,填入以前準備的修復前和修復後的 jar 包地址,還有白名單配置文件,勾選 dexPatch,進入到下一步
③ 下一步主要選擇打包的配置文件,最近點擊完成生成 patch 文件
(6)生成 patch 產物
生成 patch 產物以下:
查看產物,可使用 dex2jar 工具反解 diff.dex 文件,用 jd-gui 文件查看反解產物是否符合預期
反解後能夠看到修改的模塊:
(7)上傳發布
① 選擇上一步的產物 jar 包進行上傳
② 上傳後能夠經過白名單進行發佈,驗證 patch 的穩定性
(8)驗證下載
白名單發佈後,啓動客戶端,搜索關鍵字:DynamicRelease,能夠看到在 tool 進程有觸發下載的日誌打出。
這裏須要說明的是,這裏觸發 patch 的下載是在 tool 進程,不在主進程的主要緣由是怕因爲主進程因爲啓動致使重複閃退,致使 patch 不能下載成功,單獨在 tool 進程實現下載,儘可能提升 patch 的下載成功比例。
而後去下載目錄查看,是否下載保存成功,下載目錄在:/data/user/0/
包名/dexpatch/patch/20201023110012@20201023110012.jar
(9)殺進程啓動
確認下載保存成功後,殺掉 App,重啓查看是否生效,重啓能夠搜索關鍵字:DexPatchManager,查看 patch 生效的日誌,日誌會打印當前是否存在 patch 以及 patch 是否加載的日誌。
同時咱們也能夠就實際業務場景進行驗證,查看是否生效。
1. aar 模式集成後 patch 沒生效
aar 模式集成的時候,須要繼承框架的 QuinoxlessApplication,指定 Application 爲框架的實現類才能實現 dexpatch 的加載。QuinoxlessApplication 內主要封裝了 dexpatch 模塊的初始化和加載。
2. 使用加固後不生效
須要使用加固前的 apk 生成 patch,不能用加固後的包生成 patch。而後還須要驗證在不一樣加固廠商下的兼容表現。
3. 使用熱修復後,和 RPC 有關的調用發生 apache http 相關的 crash。
請使用 Android 官網上的方式引入 apache http client,禁止使用導入 jar 包或者 gradle implementation/compile 的方式導入 http client。不然會引發 classloader 加載類混亂。
建議方式:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
E · N · D