什么是增量更新
由于 APP 随着业务需求的不断迭代更新,功能越来越多(复杂),APK 包的体积也会越来越大,导致客户端的更新操作需要占用更多的带宽流量、时间等等,因此需寻求一些更优的更新方案。
而增量更新是将一个完整新版 APK 跟旧版 APK 进行二进制差分对比,产生更小的增量包,给到客户端进行下载更新,增量更新与完全更新相对,流程如图1所示。
增量更新的好处是能减少流量成本的消耗,降低客户端升级时间。
增量更新方案
网上现在有的增量更新方案有 BSDiff、Xdelta、Courgette(谷歌)等等。由于 Courgette 并不适用于 Android APK 更新,所以这里不对它进行对比测试。表1是针对前两者方案进行对比。
实验测试
前提条件
差分生成环境:Windows 10(64位)、CPU i5-6500(3.2GHz)、RAM 16GB
差分合成环境:SamSung SM-P583、Android 7.0、RAM 3GB
注:差分生成阶段通常在服务端进行操作,而差分合成阶段通常在手机端进行操作。
测试一(15M左右APK)
这里选取Flipboard 红板报作为测试对象,版本分别为4.3.12 (14.5MB)、4.3.13 (14.6MB),测试对比数据如下所示。
测试二(100M左右APK)
这里选取微信作为测试对象,版本分别为6.7.3 (75.5MB)、7.0.3 (104MB),测试对比数据如下所示。
测试三(500M左右 APK)
这里选取游戏包乱世王者作为测试对象,版本分别为1.6.8.25 (532MB)、1.6.12.26 (560MB),测试对比数据如下所示。
测试四(1.8GB左右 APK)
这里选取游戏包绝地求生作为测试对象,版本分别为0.13.5(1.79GB)、0.14.5 (1.86GB),测试对比数据如下所示。
注:数据来源于5次实验数据平均值
结论
由前面几组测试实验结合相关源码,可以得出如下结论:
1)差分耗时方面,Xdelta3在差分生成和差分合成都优于 BSDiff,两者的差距约10倍左右。两者的差分合成都优于差分生成;
2)内存消耗方面,随着 APK 包的大小增大,BSDiff 的内存也会翻倍增大占用,而Xdelta3 却是稳定一定范围;
3)当 APK 达到一定大小时,BSDiff 会出现差分失败(从 C 的源代码可以分析出,差分进行大量动态申请内存空间导致,同时也是占用内存大的原因,如图6所示),而 Xdelta 依旧可以差分;
4)另外,BSDiff 需将新旧文件一次性读进内存形成字符串字典,进行排序(qsufsort)、搜索(search)对比等等,产生相关 diffstring 和 extra string 块,最后进行 bzip2 压缩生成增量包(patch),同时也发现排序、搜索等差异对比操作与 bzip2 压缩生成操作各占一半时间;而 Xdelta3 应用相关窗口算法对新旧文件分块读进内存,进行差异对比生成增量包;
5)需要注意的是,两个加固包产生的增量包不能与无加固包进行合成。
综上所述,BSDiff 和 Xdelta 这两个方案都可以对 APK 进行差分。其中 BSDiff 目前使用热度较高,资料较多;而Xdelta 无论在耗时或是内存开销都有优于 BSDiff,唯一不足是资料缺少,目前没发现使用的 APP。排除 Xdelta 的不足,建议优选 Xdelta。
附(后续考虑点):
1) 维护需要相关有 C 语言开发经验;
2) 服务端多个版本差分包策略。
------------------------------------------ 2019-06-28 更新↓↓↓ -----------------------------------------
Xdelta3 二次实验测试
实验测试前提
Xdelta 版本:3.1.1
差分生成环境:Windows 10(64位)、CPU i5-6500(3.2GHz)、RAM 16GB
差分合成环境:SamSung SM-P583、Android 7.0、RAM 3GB
差分工具:Mingw-w64(x86_64-8.1.0)编译器生成 .exe 可执行文件
差分 so 库:android-ndk-r16b-windows-x86_64 交叉编译器生成 armeabi 和
armeabi-v7a 架构 .so
差分生成设置:默认压缩等级3、默认窗口大小8M
-
实验测试一 (15M 左右 APK)
测试对象:Flipboard 红板报 4.3.12 (14.5MB)、4.3.13 (14.6MB)
测试结果:如下表所示。
-
实验测试二(100M 左右 APK)
测试对象:微信 6.7.3 (75.5MB)、7.0.3 (104MB)
测试结果:如下表所示。
-
实验测试三(500M 左右 APK)
测试对象:乱世王者 1.6.8.25 (532MB)、1.6.12.26 (560MB)
测试结果:如下表所示。
-
实验测试四(1.8GB 左右 APK)
测试对象:绝地求生 0.13.5(1.79GB)、0.14.5 (1.86GB)
测试结果:如下表所示。
-
结论
经过实验测试,总结如下:
1)通过 Xdelta3 前后两次实验测试,得出的结果是相近的;
2)其次,Xdelta 3.1.1 版本相对 3.1.0 版本在耗时、内存等方面有稍微的优化;
3)另外,发现不同的编译器编译生成的 Xdelta 可执行文件对差分耗时有相关影响,例如 Mingw-w64 编译器和 CL 编译器生成执行文件,在进行差分生成操作耗时会相差一半左右(前者更优)。