众所周知在国内应用发行领域增量升级技术做的最棒的当属应用宝,从apk的增量升级覆盖度和增量文件大小上都提供了近乎完美的实现方案,应用宝基本上可以涵盖用户90%以上的安卓软件更新提醒,可以说在国内其他大型的应用发行商店都无法做到应用宝这么广泛的增量升级体验,那么应用宝到底是如何实现这一架构的呢?
应用宝采用腾讯自研的一套移动终端sdk开发框架和服务器通信框架来实现基础的网络通信功能,这样的设计方式完全区别于其他的安卓应用发型架构。豌豆荚,百度手机助手,91,以及360手机助手都没有实现二进制流的加密通信,都是json+http的方式来通信,而应用宝实现的是完整的HTTP二进制流的通信方式,这样我们是无法轻易获取应用宝的上下行通信数据,那么应用宝又是如何来实现应用的增量升级的呢?
腾讯应用宝的数据除了提供给自身使用外,还提供给android版本的腾讯浏览器客户端使用。刚好腾讯的浏览器在对用户安装的软件做分析并上传服务器的整个过程中是没有做很严格的数据加密,可以抓包反向分析出腾讯是收集的用户安装的apk文件中的manifest.mf文件。大家都知道apk文件中manifest.mf文件代表了整个apk的文件指纹,他和加密数据一道构建了apk的完整签名,来保证软件的有效性。网上流传的各种增量升级方案都是依赖于完整apk的bsdiff解决方案,这种方案必须依赖于一个apk包的md5值得完全匹配,如果整个apk包有解压和再压缩的过程,那么狠容易导致整个包中的实际内容没有变化,但是重新压缩后的apk文件md5值变化,这就导致了bsdiff在合并的过程中失败。而腾讯的巧妙做法就避免了apk再次压缩的问题,完全精准的定位了一个apk包的版本特性,那就是收集每个apk保重的manifest.mf文件的md5值。
大家都知道apk的应用包之所以很难做到增量升级是因为太多的渠道包,太多的同版本不同内部文件而导致差异化的包分发太广,服务器端无法完全收集到所有同版本的软件包来做增量文件的计算。笔者这里给出一个巧妙地方法,那就是在用户的终端上来收集manifest.mf的完整文件内容上传到服务器端,同时比对服务器端的最新版本APK包的manifest.mf文件中每一行的差异化数据,来判断用户客户端的旧版本和服务器端的新版本的差异文件,这样就可以获取到用户端的需要升级的差异化文件,从而保证了在服务器端不知道旧版本的情况下能智能分析输出差异包,应用宝之所以能支持几乎所有软件不同渠道的增量升级,我想他们的做法很有可能是在客户端的后台有定时的推送机制,就算没有支持到用户的增量升级,他们也可以做到异步的后台分析和计算,在用户下一次请求更新提醒接口时获取到增量升级的文件数据。
那么又有人会问,为什么应用宝可以用一个增量升级文件来支持到非常多的渠道升级呢?他们的做法我想也就是同一个老版本不同渠道的manifest.mf文件的互相比对,来找出差异数据的合集,这样就保证了差异文件的最大共性化,再和新版本的文件进行比对,获取到最终的增量升级文件。
服务器端计算增量升级文件的大致架构就是如此,其实并不难,主要就是如何收集用户的manifest.mf文件数据。又因为应用宝庞大的发行量,他们很容易收集到大量广泛的渠道apk包,因此大部分用户在收到升级提醒的时候都能做到增量文件的下载。
那么客户端又如何支持到增量文件的安装呢?笔者如上所述的内容完全有别于网上一大堆bsdiff,xdelta的方案,因此必须实现自己的一套增量文件合并算法。笔者已经实现了一套高性能的apk合并算法,通过实际测试,合并性能和应用宝的增量升级的合并性能旗鼓相当,同时通过大规模的测试可以得出生成的增量升级文件的大小几乎和应用宝的增量升级文件一致。对于低端手机在增量升级安装过程中的性能和内存消耗和应用宝别无二致。其实这里的实现很简单,就是利用zip文件结构的特殊性,来重新组装增量升级文件和用户手机中的apk文件,利用java本省的nio特性来加速合并apk的过程。
说了这么一大堆,还会觉得应用宝很难搞定了么?其实你也可以做出一款堪比应用宝的增量升级功能了。