Android熱補丁動態修複技術(完結篇):自動產生打包帶簽名的補丁,重構項目

來源:互聯網
上載者:User

標籤:

一、關於前面四篇博文

Android熱補丁動態修複技術(一):從Dex分包原理到熱補丁
Android熱補丁動態修複技術(二):實戰!CLASS_ISPREVERIFIED問題!
Android熱補丁動態修複技術(三)—— 使用Javassist注入位元組碼,完成熱補丁架構雛形(可使用)
Android熱補丁動態修複技術(四):自動化產生補丁——解決混淆問題

前兩篇博文主要是介紹熱補丁修複技術的一些原理和實現方案。
而後面兩篇博文主要是介紹如何使用代碼實現整個熱補丁架構,但是架構寫的真的很糟糕,很多多餘的操作。而這很大一部分原因是使用了transform,在混淆的時候transform並不好用。

以下是我在github上重構好的熱補丁架構,求star (??`ω′?)
https://github.com/AItsuki/HotFix
1. 支援混淆
2. 自動產生帶簽名的補丁包
3. 載入補丁包時會進行簽名校正


圖中的patch檔案夾就是自動產生的補丁包儲存目錄了,裡面有打成jar包之前的class,如果patch.jar打包失敗,還能繼續手動打包。

更詳細的介紹和使用方式請移步到github,再說一次:求star (??`ω′?)

二、架構的實現思路

在第四篇博文中,我們發現在混淆的情況下,transform使用起來真的很反人類,因為transform只能在混淆之前對class進行操作,無法將transform添加到混淆之後。
所以以下思路,我放棄了使用transform,而是直接在dextransform這個任務的dofirst中進行操作。

在重構項目之前,我先記錄下了這些思路和流程,然後根據這個流程來實現熱補丁架構,效率真的快了很多。

2.1 定義熱補丁架構的使用方式
  1. release簽名打包作為發布版本,每次release打包都會重建hash.txt和mapping.txt(開啟混淆的情況下才有mapping)

  2. 每次debug啟動並執行時候(直接運行項目或者buildapk),都會通過校正hash.txt和mapping.txt產生已簽名補丁包。
    直接將補丁包放到sdcard中即可完成熱修複

  3. 載入補丁的時候需要進行簽名校正,防止惡意代碼注入

2.2 代碼流程

拋棄transform,使用純hook的方式實現。
主要hook的task有這幾個:

  • transformClassesWithDexForRelease
  • transformClassesWithDexForDebug
  • transformClassesAndResourcesWithProguardForRelease
  • transformClassesAndResourcesWithProguardForDebug

不混淆的情況:
transformClassesWithDexForRelease
dofirst —— 遍曆輸入檔案,產生md5儲存好(hash.txt),然後注入代碼

transformClassesWithDexForDebug
dofirst —— 遍曆輸入檔案,產生md5,和hash對比,將改變過的類複製到補丁檔案夾,然後注入代碼

混淆的情況:
transformClassesAndResourcesWithProguardForRelease
dolast —— 遍曆輸出檔案,產生md5儲存好(hash.txt),然後注入代碼,將mapping儲存好

transformClassesAndResourcesWithProguardForDebug(需要使用applymapping)
dolast —— 遍曆輸出檔案,產生md5,和hash對比,將改變過的類複製到補丁檔案夾,然後注入代碼

開啟混淆後task的執行順序是proguard –> dex
因為dex永遠是在最後面執行,所以注入代碼和產生補丁這些操作都只需要hook dex就可以了
但是開啟混淆的時候,dex dofirst需要做的事情還是有點不同的,我們可以通過一個變數來控制 def minify = false

hook proguard,在proguardTransform執行的時候覆制minify = true
這樣就可以控制混淆和不混淆兩種情況了。

2.3 實際遇到的問題

1、 不clean項目,第二次運行release打包不會注入代碼
這是因為gradle的增量式構建,up-to-date,task不執行
解決方式:
dexRelease.outputs.upToDateWhen {false} 讓task一直都執行
http://stackoverflow.com/questions/7289874/resetting-the-up-to-date-property-of-gradle-tasks

2、如果有使用到自訂控制項,在xml的preView視窗會報null 指標異常
這是因為自訂控制項已經被注入了代碼,而預覽視窗的時候並沒有載入hack.jar,找不到AntilazyLoad.class,所以報null 指標。
解決方式:
使用pluginExtention,在build.gradle中組態變數,控制在debug模式下是否注入代碼。
,這裡添加了兩個Extention

3、如何applymapping
applymapping的作用是複用上一次的混淆規則。
所以我們需要將release產生的mapping.txt應用到debug的混淆上,否則可能無法正確的產生補丁。
解決方式:
第一種:
手動設定debug的混淆檔案

第二種:
1. 在gradle 1.5以下時,可以直接task.applyMapping(File file)的方式在代碼中動態添加
2. 在gradle1.5以上時,因為proguard的transform是一個特殊的task,所以並不能直接applyMapping,需要做一些強轉。
(proguardDebug即transformClassesAndResourcesWithProguardForDebug)

4、開啟混淆後的Release簽名打包,如果debug模式不開啟混淆的話,會將所有類都打包成補丁。
這是因為,如果debug模式不開啟混淆,那麼就會拿不混淆的代碼和Release已經混淆的代碼進行校正,md5肯定不一致,所以會將所有類打包成補丁包。
解決方式:
暫時沒有好辦法,老老實實開啟混淆吧。Debug是否開啟混淆要和Release保持一致

5、如何簽名補丁
補丁的簽名主要用到的是jdk的工具,jarsigner.exe。使用代碼調用命令列即可

6、如何進行簽名校正
首先,debug安裝的app不需要進行校正,這是檢測當前app是否是debug簽名的方法。
http://blog.csdn.net/luohai859/article/details/44679085

然後,這是校正補丁包和app簽名是否一致
http://blog.csdn.net/hudashi/article/details/8245105

7、android 6.0無法從sdcard載入補丁包
運行時許可權機制的問題,可以將補丁包放到app私人空間載入。

8、 androidStudio 2.0以上用到了instantRun,這是否會對debug自動產生補丁包產生影響。
這個問題我還沒有測試,如果真的有影響的話也有很簡單的解決方式,直接使用簽名打包debug也可以產生補丁包。

三、參考項目

https://github.com/jasonross/Nuwa
https://github.com/bunnyblue/DroidFix
https://github.com/Livyli/AndHotFix
主要是第三個,簽名校正的思路來源於它

四、寫在後面

終於算是完成了熱補丁架構了,其中過程真的累人啊!
整個架構的實現思路比較清晰簡單,代碼量也不超過1000行,很適合正在學習這個技術的朋友們。

求star,求star,第一個上傳到github的項目求star (??`ω′?)
https://github.com/AItsuki/HotFix

Android熱補丁動態修複技術(完結篇):自動產生打包帶簽名的補丁,重構項目

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.