1. 程式人生 > >Andfix熱修復框架原理及源代碼解析-上篇

Andfix熱修復框架原理及源代碼解析-上篇

ren oid 聯系 pass 重命名 命名 key () 提示

熱補丁介紹及Andfix的使用
Andfix熱修復框架原理及源代碼解析-上篇

Andfix熱修復框架原理及源代碼解析-下篇

1.不知道怎樣使用的同學,建議看看我上一篇寫的介紹熱補丁和Andfix的使用,這樣你才有一個大概的框架。通過使用Andfix,事實上我們心中會有一個大概的輪廓,它的工作原理,大概就是。所謂的補丁文件。就是通過打包工具apkpatch比對新的apk和舊的apk之間的差異。

然後讓我們的舊包執行的時候。就載入它,把曾經的一些信息替換掉。

我們如今就抱著這個慷慨向去深入源代碼探個到底!

。首先看下Demo裏面Application的代碼。

技術分享

2.一開始實例化PatchManager

。然後調用init()這種方法,我們跟進去看看。

我凝視的非常具體,大致就是從SharedPreferences讀取曾經存的版本號和你傳過來的版本號進行比對,假設兩者版本號不一致就刪除本地patch。否則調用initPatchs()這種方法。

技術分享

3.分析下initPatchs()它做了什麽,事實上代碼非常easy,就是把mPatchDir目錄下的文件作為參數傳給了addPatch(File)方法,然後調用addPatch()方法。addPatch方法的作用看以下的凝視,寫的非常清楚。

技術分享

4.我們能夠看到addPatch()方法裏面會實例化Patch,我們跟進去看看實例化過程中,它又幹了什麽事。

技術分享

它裏面調用了init()方法,能夠看到裏面有JarFile, JarEntry, Manifest, Attributes,通過它們一層層的從Jar文件裏獲取對應的值,提到這裏大家可能會奇怪,明明是.patch文件,怎麽又變成Jar文件了?事實上是通過阿裏打補丁包工具生成補丁的時候寫入對應的值。補丁文件事實上就相到於jar

包。僅僅只是它們的擴展名不同而已。提到這裏我們就來單獨的探索下,補丁文件是怎麽一步步生成的。由於阿裏沒有對打補丁工具進行加密和混淆。我們能夠使用jdgui打開查看。

所需對應的工具代碼demo等我都統一放在以下的下載鏈接裏面。有須要的自行取下。


5.好了,我們如今來分析下補丁文件怎樣生成的,用jdgui打開apkpatch-1.0.3。先從main方法開始。

技術分享

能夠看到:下圖1部分就是我們前面介紹怎樣使用命令行打補丁包的命令,檢查命令行是否有那些參數。假設沒有要求的參數,就給用戶對應的提示。

第二部分。我們在打正式包的時候,會指定keystore,password,alias,entry相關參數。

另外name就是最後生成的文件,能夠忽略。

技術分享

Main函數最後一個方法是我們的大頭戲。上面的參數傳給ApkPatch進行初始化。然後調用doPatch()方法。

技術分享

我們再跟進去。看看ApkPatch初始化的過程中,做了什麽。

技術分享

調用了父類的方法,我們再看看父類Build.

技術分享

幹的事情事實上比較簡單。就是給變量進行賦值。能夠看到out,我們的輸出文件就是這麽來的,沒有的話,它會自己創建一個。

然後我們再回到apkPatch.doPatch()這種方法。

看看這種方法裏面是什麽。

技術分享

這種方法主要做的就是在我們的out輸出文件裏生成一個smali目錄,還有diff.dex, diff.apatch文件。

能夠找到你的輸出文件確認下。

技術分享

DiffInfo相當於一個存儲新包和舊包差異信息的容器來,通過diff方法將二者的差異信息給info.然後就是三個最重要的方法,buildCode(), build(),release()。我們接下來一個個的看下,他們到底為何這麽重要。

技術分享

看到baksmali和smali,反編譯過apk的同學一定不陌生,這就是dex的打包工具和解包工具。關於這個詳細就不深入了,有興趣的同學能夠深入了解下。這種方法的返回值將DiffInfo中新加入的classes和改動過的classes做了一個重命名。然後保存了起來,同一時候,將相關內容寫入smali文件裏。

為什麽要進行重命名,事實上是為了防止和之前安裝的Dex文件名稱字沖突。

技術分享

接下來看看build(outFile, dexFile),首先從keystone裏面獲取應用相關簽名,將getMeta()中獲取的Manifest內容寫入"META-INF/PATCH.MF"文件裏。getMeta()方法上面,實例化PatchBuilder,然後調用writeMeta(getMeta())。我們走進去先看看。

技術分享


這個就是將dexFile和簽名相關信息寫入classes.dex文件裏。能夠有點蒙。

我們就看看writeFile()方法。

技術分享

SignedJarBuilder的構造方法做了一些初始化和賦值操作。提到這個是方便可以理解writeFile()這種方法。

writeFile裏面調用了writeEntry(),我們看看它。

技術分享

這種方法就是從input輸入流中讀取buffer數據然後寫入到entry。然後聯系到我上面提到的將dexfile和簽名相關信息寫入到classes.dex裏面。應該能好理解點。

上面提了一大堆,我們的東西準備的差點兒相同了,如今就看看最後一個方法ApkPatch release(this.out, dexFile, outFile)

技術分享

這種方法就是將dexFile進行md5加密,把build(outFile, dexFile);函數中生成的outFile重命名。哈哈。看到”.patch”有沒有非常激動!

我們的補丁包一開始的命名就是一長串。好了,到這裏,補丁文件就生成了。接下來我們看看,怎麽來使用它。

堅持就是勝利,立即你就要熬過頭了...沒辦法。別人團隊花了這麽長時間做的,想分析就得花時間。

相關資料工具及demo下載地址:http://pan.baidu.com/s/1hsdcs7a

轉載請註明轉自:http://blog.csdn.net/u011176685/article/details/50984796

歡迎關註個人微信公眾號,專註於Android深度文章和移動前沿技術分享

技術分享

Andfix熱修復框架原理及源代碼解析-上篇