Android 增量更新
BSDiff / bspatch
http://www.daemonology.net/bsdiff/
android的代码目录下 externalsdiff
bsdiff是二进制差分工具,其对应的 bspatch 是相应的补丁合成工具
命令:bsdiff oldfile newfile patchfile
用户在下载了xx.patch补丁包后,需要用到补丁所对应的apk,即原来系统安装的旧版本apk和补丁合成的bspatch工具。
系统旧版本的apk可以通过copy系统data/app目录下的apk文件获取,而补丁合成的bspatch可以通过将bspatch源码稍作修改,封装成一个so库,供手机端调用。
bspatch的命令格式为:
bspatch oldfile newfile patchfile
和差分时的参数一样。合成新的apk便可以用于安装。
以上只是简单的操作原理,增量升级还涉及很多其他方面,例如,升级补丁校验等问题,可以参考android源码中bootable
ecoveryapplypatch的相关操作
不足
增量升级并非完美无缺的升级方式,至少存在以下两点不足:
1.增量升级是以两个应用版本之间的差异来生成补丁的,你无法保证用户每次的及时升级到最新,所以你必须对你所发布的每一个版本都和最新的版本作差分,以便使所有版本的用户都可以差分升级,这样操作相对于原来的整包升级较为繁琐,不过可以通过自动化的脚本批量生成。
2.增量升级成功的前提是,用户手机端必须有能够让你拷贝出来且与你服务器用于差分的版本一致的apk,这样就存在,例如,系统内置的apk无法获取到,无法进行增量升级;对于某些与你差分版本一致,但是内容有过修改的(比如破解版apk),这样也是无法进行增量升级的,为了防止合成补丁错误,最好在补丁合成前对旧版本的apk进行sha1sum校验,保证基础包的一致性。
由于apk本质上是一个压缩包,压缩会导致做差分的时候效果并没有那么明显,差分包与新文件大小还是比较接近。所以我们可以做更进一步的优化,首先在服务端将apk1和apk2解压,逐文件对比。另外创建一个清单记录,如果有文件增加则标记增加,删除做删除标记,更改则对文件做差分,类似git的原理,然后将清单和差分文件最后一起打包。客户端则根据下载下来的清单和差分文件做逆操作即可。
使用bsdiff进行差分升级,还并不是最优的方式,google在它的Chromium项目中,对这个差分算法进行了优化,优化后的版本叫做小胡瓜Courgette,据说性能优化了很多不是一个数量级了,官方的一个例子:
Full update 10,385,920
bsdiff update 704,512
Courgette update 78,848