如果app依賴本地更新,更新比較頻繁的話,每次更新都要讓用戶下載完整安裝包励翼,用戶體驗(yàn)會比較差。目前辜荠,很多應(yīng)用商店都實(shí)現(xiàn)了apk的增量更新
- 正常apk更新邏輯:
- 打包V1.0版本汽抚,大小30M,用戶安裝完成
- 更新V1.1版本伯病,大小31M造烁,上傳服務(wù)器得到遠(yuǎn)程鏈接,用戶打開app收到更新提示午笛,下載V1.1的apk惭蟋,覆蓋安裝,更新完成
- 增量更新apk邏輯
- 打包V1.0版本药磺,大小30M告组,用戶安裝完成
- 更新V1.1版本,大小31M癌佩,上傳服務(wù)器得到遠(yuǎn)程鏈接 https://www.abc.com/apk/V1.1.apk
- 對比V1.1和V1.0木缝,生成差異包 V1.1_1.0.patch ,上傳服務(wù)器得到遠(yuǎn)程鏈接 https://www.abc.com/apk/V1.1_1.0.patch
- 用戶打開app收到更新提示驼卖,獲取到patch和apk兩個(gè)鏈接氨肌,下載patch文件(當(dāng)然需要做判斷鸿秆,比如V1.1_1.0酌畜,需要判斷當(dāng)前安裝的是否是1.0版本)
- patch文件和本地當(dāng)前版本apk文件進(jìn)行合并卿叽,生成新的apk文件
- 安裝新的apk文件
- 以上步驟如果出現(xiàn)異常,就再下載安裝包執(zhí)行正常apk更新邏輯考婴;
一、 差異包生成
使用bsdiff工具生成差異包沥阱。鏈接 http://www.daemonology.net/bsdiff/
但是官網(wǎng)好像無法下載了缎罢,已經(jīng)備份了百度網(wǎng)盤 鏈接:https://pan.baidu.com/s/1SyGG_wsbaPbwHB0d0gwHOA
提取碼:8888
準(zhǔn)備V1.0和V1.1版本的apk:
使用命令:
bsdiff oldfile newfile patchfile
生成新包。
二舰始、 安卓端代碼
- 創(chuàng)建工程,配置好ndk環(huán)境
2.添加BSPatchUtil
代碼如下:
package com.dxl.testbatch.util
object BSPatchUtil {
/**
* @param basePath 基礎(chǔ)文件
* @param syntheticPath 合成的目標(biāo)文件
* @param patchPath 合成所需要的差分文件
* @return main 返回值
*/
@JvmStatic
external fun bspatch(basePath: String, syntheticPath: String, patchPath: String): Int
init {
System.loadLibrary("bspatch")
}
}
- 添加bspatch對應(yīng)的C代碼咽袜,我已經(jīng)整理好了丸卷,地址鏈接:https://pan.baidu.com/s/1czefBklPWz_0zSmS8Zb0AQ
提取碼:8888
注意:需要修改bspatch.c文件中的Java_com_dxl_testbatch_util_BSPatchUtil_bspatch方法簽名:改為BSPatchUtil 的包名,例如BSPatchUtil對應(yīng)的路徑為com.dxl.testbatch.util.BSPatchUtil谜嫉,那么native方法簽名就是Java_com_dxl_testbatch_util_BSPatchUtil_bspatch
目錄結(jié)構(gòu)如下:
-
修改app build.gradle
make project
測試
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (event?.action == MotionEvent.ACTION_UP) {
//當(dāng)前apk路徑沐兰,實(shí)際開發(fā)中用這個(gè)匕垫,當(dāng)前沒有使用
val sourceDir =
packageManager.getApplicationInfo(BuildConfig.APPLICATION_ID, 0).sourceDir
val file = File(sourceDir)
thread {
val old = getExternalFilesDir("apk")!!.absolutePath + "/239.apk"
val new = getExternalFilesDir("apk")!!.absolutePath + "/new.apk"
val patch = getExternalFilesDir("apk")!!.absolutePath + "/1.patch"
val time = measureTimeMillis {
BSPatchUtil.bspatch(old, new, patch)
}
runOnUiThread {
Toast.makeText(this, "打包成功,用時(shí)$time~", Toast.LENGTH_SHORT).show()
}
}
return true
}
return super.onTouchEvent(event)
}
-
生成so包
編譯一次之后寞秃,會自動生成so文件偶惠,路徑如下:
將指定的so文件移動到指定目錄中:
刪除build.gradle中添加的編譯配置
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
刪除cpp目錄,重新編譯即可绑改。
代碼:https://github.com/limpid100/TestBatch
參考: bspatch tools for android https://github.com/krmao/bspatch
Android增量更新原理和實(shí)踐 http://www.reibang.com/p/9b0c10270759