Andfix熱修復框架原理及原始碼解析-上篇
1.不知道如何使用的同學,建議看看我上一篇寫的介紹熱補丁和Andfix的使用,這樣你才有一個大概的框架。通過使用Andfix,其實我們心中會有一個大概的輪廓,它的工作原理,大概就是,所謂的補丁檔案,就是通過打包工具apkpatch比對新的apk和舊的apk之間的差異。然後讓我們的舊包執行的時候,就載入它,把以前的一些資訊替換掉。我們現在就抱著這個大方向去深入原始碼探個究竟!!首先看下Demo裡面Application的程式碼。
2.一開始例項化PatchManager,然後呼叫init()這個方法,我們跟進去看看。我註釋的很詳細,大致就是從SharedPreferences讀取以前存的版本和你傳過來的版本進行比對,如果兩者版本不一致就刪除本地
3.分析下initPatchs()它做了什麼,其實程式碼很簡單,就是把mPatchDir資料夾下的檔案作為引數傳給了addPatch(File)方法,然後呼叫addPatch()方法,addPatch方法的作用看下面的註釋,寫的很清楚。
4.我們可以看到addPatch()方法裡面會例項化Patch,我們跟進去看看例項化過程中,它又幹了什麼事。
它裡面呼叫了init()方法,可以看到裡面有JarFile, JarEntry, Manifest, Attributes,通過它們一層層的從Jar檔案中獲取相應的值,提到這裡大家可能會奇怪
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”有沒有很激動!!我們的補丁包一開始的命名就是一長串。好了,到這裡,補丁檔案就生成了!接下來我們看看,怎麼來使用它。堅持就是勝利,馬上你就要熬過頭了...沒辦法,別人團隊花了這麼長時間做的,想分析就得花時間。
歡迎關注個人微信公眾號,專注於Android深度文章和移動前沿技術分享