Android增量升級方案
結束了愉快的週末,又到了給大家更新的時候。
本篇來自公衆號“老司機” 何以誠 的投稿,分享瞭如何進行增量升級(亦作增量更新)。文中提到的一個插件化框架 Small,有興趣的朋友可以訪問最後的github地址查看。
何以誠 的博客地址:
http://blog.csdn.net/u013022222
隨着業務的發展,安裝包的體積也在不斷的增大,這時候,如果要版本更新,用戶不得不去下載完整的安裝包。但是如果使用增量升級方案,用戶只需要下載新舊版本的差異包,然後在本地合成就行,這樣省時省力。我們可以看下某產品使用增量升級時的數據:
xxx.2.4.0000.apk 32MB
xxx.2.5.0000.apk 28MB
差異包 6.3MB
其中增量包就是上文提到的差異包,可見 用戶每次升級只需下載差異包就行,省時省力。
其原理就是,我們在服務器端先拿新版本安裝包和舊版本安裝包進行對比,在生成差異包之後下發,之後客戶端根據對應的差異包和本地舊版本安裝包合成,便生成了新版本安裝包。
下載編譯差分合並工具
apk文件的差分和合並都是使用的開源的二進制比較工具 bsdiff 實現,值得注意的是,該工具依賴 bizp2 這個庫。
在下載完畢後,直接make便可以編譯工具,不過我在一臺蘋果機器上編譯的時候出現了一點問題,那時候make文件沒法正確的讀取,所以我修改了make文件,讀者編譯的時候(僅限mac, linux)只需要運行 install.sh 腳本就行。這部分的代碼我已經單獨抽出來作爲一個 repo,讀者喜歡可以自行star,然後下載編譯 repo。
bsdiff
http://www.daemonology.net/bsdiff
bizp2
http://www.bzip.org
repo
https://github.com/ChanJLee/AndroidPatch
生成差異包
如果你剛剛編譯成了 bsdiff,在命令行裏面輸入 bsdiff 或者 bspatch 就會出現如下的信息:
其中 bsdiff 用於比較新舊文件的差異部分並生成差異包,bspatch 根據之前差異包和舊文件生成新文件,我們可以從這兩個可執行文件的報錯信息看出該命令如何使用。我們這裏有兩個文件:new.so 和 old.so。
之後我們運行 diff old.so new.so patch.so 便生成了差異包 patch.so。
合成新版本
通過剛剛的介紹,我們已經在Android端實現了相關的庫,只需要簡單的調用:
YPatch.patch(oldFilePath, newFilePath, patchFilePatch)
便可以將新版本存放到 newFilePath 指定的目錄下。
上面好像都是在講原理,沒有具體的實踐講解的話,估計讀者還是不懂,我們現在就結合 Small框架 來看看如何做到增量更新。
對於我們的 Small框架,我們要知道,它把每個插件都編譯成 .so文件,然後存放到app的 native目錄 下,不過,如果它發現自己的 download目錄 有新的插件,那麼就會去加載 download目錄 下的插件,並且這種加載優先權是最大的,也就是說它會 優先加載download目錄 下的插件。
所以,如果我們要做增量更新,舊文件就從app的native目錄進行讀取,然後從服務器端下載增量包,最後合成的文件存放到 download目錄,這樣每次插件啓動都會到 download目錄 下加載新的插件。
實現:
可以看到這個函數中出現的 pluginUri,它其實對應的是 bundle.json 中插件的 uri:
也就是這裏的 main 以及 setting。
而這個 bundle.json 就是宿主中 asset 下的 small配置文件:
示例代碼:
OkSmall.merge(LaunchActivity.this, "setting", "http://192.168.1.100:8080/patch.so");
Toast.makeText(LaunchActivity.this, "重啓應用後更新生效", Toast.LENGTH_SHORT).show();
至此,所有的內容已經介紹完畢。
更新插件的時候要記得把插件的 versionCode 加大,比如 我們這裏的 setting 插件:
修改它的 build.gradle 文件:
要記得加大11行的數值,不然加載還是不成功的。
Small框架
https://github.com/wequick/Small
Android增量升級通用代碼
https://github.com/ChanJLee/AndroidPatch
結合Small的增量升級方案
https://github.com/ChanJLee/SmallPatch