Android Apk增量更新
前言
有關APK更新的技術比較多,例如:增量更新、插件式開發、熱修復、RN、靜默安裝。
下面簡單介紹一下:
什麽是增量更新?
增量更新就是原有app的基礎上只更新發生變化的地方,其余保持原樣。
與原來每次更新都要下載完整apk包的做法相比,這樣做的好處顯而易見:每次變化的地方總是比較少,因此更新包的體積就會小很多。
增量更新的流程
1.APP檢測最新版本:把當前版本告訴服務端,服務端進行判斷。
如果有新版本,服務端需要對當前版本的APK與最新版本的APK進行一次差分,產生patch差分文件。(或者新版本的APK上傳到服務端的時候就已經差分好了)
2.APP在後臺下載差分文件,進行文件的MD5校驗,在本地進行合並(跟本地的data目錄下面的APK文件合並),合並出最新的APK之後,提示用戶安裝。
3.增量更新的最終目的:省流量地更新宿主APK。
差分的處理比較麻煩的地方就是要針對不同的應用市場渠道和眾多不同版本進行差分。
註意:新版本有可能比舊版本小,差分只是把變化的部分記錄下來。
服務器端行為(後臺工程師操作)
1.下載拆分和合並要用的第三方庫(bsdiff、bzip2)
我們使用到的第三方庫是:Binary diff,簡稱bsdiff,這個庫專門用來實現文件的差分和合並的,它的官網如下:
http://www.daemonology.net/bsdiff/
在這裏我們可以點擊文中的"here"下載源碼,這是Linux源碼。也可以下載Windows版本的源碼,點擊"Windows port"。
建議Windows 下用sbsdiff4.3-win32-src編譯
這個庫引用了bzip2這個庫,官網如下:
http://www.bzip.org/
2.編譯第三方庫源碼生成dll動態庫
為了方便演示,我在Windows 10平臺下用VS2017編譯,實際情況服務器大都在Linux系統下運行,這個大家去測試吧。
Windows 下生成dll動態庫參考 Android NDK開發之旅10--JNI--JNI開發流程
所用到資源
註意:com_haocai_bsdiff_BsDiff.h 是根據Java文件聲明得到的,步驟省略。
編譯過程中會有以下錯誤提示
字符集問題
用了不安全和過時的函數
SDL檢查不通過
以下是解決辦法:
配置字符集
忽略不安全和過時的函數警告
設置SDL檢查形式
另外,可能報頭文件找不到的錯誤,這有可能是編碼問題,因為外國人使用的蘋果電腦跟Windows電腦的編譯不一致產生的。可以通過Notepad++的轉碼功能進行轉碼,全部轉為UTF-8無BOM格式編碼即可,Windows、Linux通用的。
我們項目屬性裏面的生成配置裏面選擇DLL,並且修改解決方案為你的電腦的對應平臺,然後編譯,生成DLL動態庫文件。
3.Java代碼調用
創建Web項目,用來做APP的服務端。創建工具類專門用於產生差分包:
其中JNI的實現如下(該實現寫在bsdiff.cpp中):
通過研究bsdiff的源碼,我們發現bsdiff.cpp裏面的main函數就是入口函數,避免歧義把函數名main改為bsdiff_main,然後通過JNI去調用。
根據bsdiff.cpp中bsdiff_main函數方法中有以下關鍵語句
if (argc != 4) errx(1, "usage: %s oldfile newfile patchfile\n", argv[0]);
根據提示需要傳入4個參數:
argv[0] = "bsdiff";//這個參數沒用
argv[1] = oldPath;//舊APK文件路徑
argv[2] = newPath;/新APK文件路徑
argv[3] = patchPath;//APK差分文件路徑
然後我們準備兩個APK文件,不同版本的,最好Java代碼、資源都不一樣。
寫一個Java測試類生成差分包:
生成結果如下圖所示:
apk.patch為生成的差分包
註意:
test_new.apk、test_old.apk 要先放在目標目錄
bsdiff.cpp中生成差分包的程序方法是異步的,所以生成完整的apk.patch可能要等一下。apk.patch體積大小停止增長,表示生成結束。
4.簡單搭建後臺JavaWeb供Android前端下載apk.patch差分包
參考 Intellij idea創建javaWeb以及Servlet簡單實現
在瀏覽器中輸入
http://localhost:8080/App_Update_Web/patchfile/apk.patch
如圖,提示可以下載
服務器搭建完畢。
Android客戶端行為
1.編譯合並要用的第三方庫(bsdiff、bzip2)
對應的Java代碼如下:
在Android端,我們需要把bzip2以及bsdiff的文件拷貝到jni目錄裏面,同樣的,我們只需要編譯一個bspatch.c源文件即可。
ndk-build所需要的文件
由於Android手機本來就是Linux系統,因此我們直接使用bsdiff的Linux版本的庫即可。
跟服務器端一樣,在這裏我們把bspatch.c中的main函數改為bspatch_main,提供JNI調用:
代碼v1.0差分包合並核心代碼如下:
主要的邏輯在fileDownload方法中,我們先下載差分包,然後在本地合成,最後提示用戶安裝。
為了達到明顯的效果,兩個版本可以增刪一些資源文件、修改Java代碼、布局文件等。
註意:這裏7.0可能會有問題,把路徑暴露給別的app,需要FileProvider去實現(不難,這個留給大家去做吧)。
源碼下載:https://github.com/kpioneer123/DiffInstallApp
Android Apk增量更新