前言
传统的APP更新,每一次产品迭代,都需要用户下载新的完整apk安装包后,重新安装。当apk的体积达到一定程度时,这种更新就会特别的浪费时间和流量,同时也影响用户体验。针对这一问题,目前市场上出现了很多热更新、热修复等技术如阿里的Anfix、腾讯的Tinker框架等。其中,腾讯的Tinker框架实现原理上,就用到了开源的文件差分工具bsdiff/bspatch。我们今天就来介绍一下基于bsdiff差分工具的增量更新技术。
增量更新原理
增量更新的原理是,利用工具(bsdiff工具),将旧版本和新版本的apk安装包二进制文件进行对比,得到差分包(即两个版本的差异文件),然后下发到客户端(已安装旧版本),而这个差分文件的大小肯定是小于新的apk文件大小的。客户端得到这个差分文件之后,本地在使用bspatch工具进行差分文件和本地已经安装的旧apk包进行合并成新的apk包文件,然后在进行升级安装。
在这个过程中,客户端在访问服务端的时候可能需要携带旧apk包的md5,应用包名,版本号等信息,服务端获取到之后会去数据库中查询其对应的本次需要升级的apk包以及旧版本号对应的旧apk包,然后进行差分处理得到差分文件,在下发到客户端即可。
实战
一、前期准备
前面已经介绍了增量更新的原理,这里采用bsdiff(Binary diff)开源库来实现新旧包差分比较。Binary diff是依赖 bzip 压缩库的开源库,所以也要下bzip库源码。
linux 的相关 diff/patch 下载 http://www.daemonology.net/bsdiff/
windows 上的 bsdiff http://sites.inka.de/tesla/others.html#bsdiff
相关依赖 bzip 文档及下载http://www.bzip.org/downloads.html
二、java服务端实现
- 分析bsdiff.cpp源码,找到main函数入口,因为这里我们要利用这个开源库通过jni生成动态库,也即是通过jni层来调用这个方法去实现我们的功能,即把main函数重新命名,方便我们调用;
//argc必须为4 //*argv[]传四个参数:argv[0]->任意值 argv[1]->oldfile argv[2]->newfile argv[3]->patchfile int bsdiffMain(int argc,char *argv[]) { int fd; u_char *old,*_new; off_t oldsize,newsize; off_t *I,*V; off_t scan,pos,len; off_t lastscan,lastpos,lastoffset; off_t oldscore,scsc; off_t s,Sf,lenf,Sb,lenb; off_t overlap,Ss,lens;