一、前言
最近在看熱修復相關的框架,之前我們已經看過了阿里的Dexposed和AndFix這兩個框架了,不了解的同學可以點擊這里進行查看:Dexposed框架原理解析 和 AndFix熱修復框架原理解析,然后還有最近很火的一個是騰訊的Tinker熱修復框架,再看他的原理實現的時候,發現了他使用到了開源的文件差分工具bsdiff/bspatch,所以就單獨用這篇文章來詳細介紹一下這個工具,因為這個工具有一個很大的用途就是增量更新,也就是我們看到現在大部分的應用市場推出的省流量更新應用的效果:
看到了吧,會提示你省了很多流量,按照以前常規的思路就是有應用更新了,就直接把更新的apk包下載然后升級安裝,那么如果一個apk包很大,如果在非Wifi情況下還是很耗流量的,但是有時候我們會發現一個應用在升級的時候只是改了部分功能,有些功能並沒有改,那么就想了如果要是能直接更新變動的功能的話,那么就會下載數據非常少了。這就需要借助我們幾天介紹的這個文件差分工具bsdiff/bspatch了。
二、原理解析
上面的省流量更新原理可以這么理解:服務端可以借助bsdiff工具,比對新舊apk包的文件,獲取到差分文件之后下發到客戶端,而這個差分文件的大小肯定是小於新的apk文件大小的。客戶端得到這個差分文件之后,本地在使用bspatch工具進行差分文件和本地已經安裝的舊apk包進行合並成新的apk包文件,然后在進行升級安裝。
在這個過程中,客戶端在訪問服務端的時候可能需要攜帶舊apk包的md5,應用包名,版本號等信息,服務端獲取到之后會去數據庫中查詢其對應的本次需要升級的apk包以及舊版本號對應的舊apk包,然后進行差分處理得到差分文件,在下發到客戶端即可。
三、案例代碼分析
上面了解了原理之后,下面就直接看通過源碼進行操作吧,前面已經說過了,bsdiff和bspatch這個功能源碼是開源的,可以從網上查找,關於他們的源碼這里不做太多的介紹,因為是純C代碼,分析起來沒什么意思,可以自行閱讀即可,因為是純C語言的,所以如果我們想在Android端使用的話那么就需要使用NDK進行開發了,需要在上層用native方法進行關聯訪問,這個其實也沒什么大的問題,而關於服務端那邊進行文件差分操作,這個已經有現成的工具了,也是用C語言編譯的可執行文件。所以下面第一步先來解決客戶端的NDK開發工作:
第一步:定義native方法
這個native方法還是比較簡單的,參數也很容易理解,新舊apk包路徑,差分包路徑。
第二步:使用javah生成頭文件
注意:這里的命令是運行在源碼src目錄下,采用的類全名方式生成的。會在當前目錄下生成對應的頭文件:
第三步:新建jni目錄
右擊項目,選擇Android Tools=》Add Native Support,點擊下一步即可,在項目中會生成一個jni目錄,然后我們把上面生成的頭文件拷貝到這里,同時把網上找到的bsdiff和bspatch源碼也拷貝到這個目錄下:
然后記得添加編譯腳本mk文件即可。
第四步:編寫native層代碼
這里代碼非常簡單,把上層傳遞的參數直接傳入到applypatch函數中即可,相當於我們什么都不用做。
第五步:使用編譯之后的bsdiff工具生成差分文件patch
在這個目錄下運行命令:bsdiff.exe demo_old.apk demo_new.apk demo.patch;然后生成了demo.patch文件,我們可以將其拷貝到sdcard目錄下。
第六步:客戶端編寫代碼進行差分文件合並
這里通過sdcard目錄下的舊apk文件和生成的patch文件進行合並工作,生成新的apk文件,生成之后直接進行升級安裝。
注意:這里我們為了懶,把舊apk直接拷貝到sdcard目錄了,而在實際開發中我們應該通過系統提供的方法直接獲取已經安裝應用的apk文件路徑的:
四、運行結果
上面的代碼已經編寫完成了,下面就直接運行即可,會自動編譯native的代碼:
然后運行結果:
這樣就簡單實現了應用的增量升級了。而這個技術在后面介紹Tinker框架的時候會涉及到,他內部做了差分文件也是借助這個工具來進行操作的。
項目下載地址:https://github.com/fourbrother/android_diffupdate
五、總結
現在的熱修復框架都會涉及到修復文件,而這個文件現在都可能叫做差分文件。就是需要真正修復問題的文件包。這個技術在早期應用市場中的省流量升級已經體現出來了。