随着android应用体积的不断增大,以及应用版本发布的不断更迭,用户的升级成了一个问题,google也意识到不断更新应用对用户流量的损耗,在Google I/O 上提及的 Smart App update,即应用增量升级,或者叫做差分升级的做法,并在新版本的Google Play中得到支持,某天在和群友聊天是扯到这方面的话题,好奇就稍微研究了一下。
增量升级的原理
今天我们就来实现类似的应用的增量升级。其实增量升级的原理很简单,即首先将应用的旧版本Apk与新版本Apk做差分,得到更新的部分的补丁,例如旧版本的APK有5M,新版的有8M,更新的部分则可能只有3M左右(这里需要说明的是,得到的差分包大小并不是简单的相减,因为其实需要包含一些上下文相关的东西),使用差分升级的好处显而易见,那么你不需要下载完整的8M文件,只需要下载更新部分就可以,而更新部分可能只有3、4M,可以很大程度上减少流量的损失。
在用户下载了差分包之后,需要在手机端将他们组合起来。可以参考的做法是先将手机端的旧版本软件(多半在/data/下),复制到SD卡或者cache中,将它们和之前的差分patch进行组合,得到一个新版本的apk应用,如果不出意外的话,这个生成的apk和你之前做差分的apk是一致的。
增量升级的操作
在了解基本的原理之后,我们来逐步解决其中的各个难点。首先是差分包patch的生成。如果做过android手机OTA升级的同学应该注意到,在update.zip中的patch文件夹中有需要与系统文件同名但是以xxx.p 为后缀的文件,他们就是生成的差分patch文件。我们可以借鉴OTA系统升级的差分生成工具来生成我们单个应用apk的差分patch文件。
OTA系统差分包的制作,使用命令:
[html] view plaincopyprint?
./build/tools/releasetools/ota_from_target_files -n -i <旧包> <新包> <差分包名>
在查阅ota_from_target_files 的代码可知,是在函数WriteIncrementalOTAPackage里生成差分包的,在这个函数里边创建了common.Difference这个类,我们继续跟进,在common.py中的类 class Difference(object):里可以看到:
[html] view plaincopyprint?
diff_program = DIFF_PROGRAM_BY_EXT.get(ext, "bsdiff")
至此我们就看到了android中提供我们用来制作差分增量升级包的工具,"bsdiff",这是一个很牛X开源的二进制差分工具.相关的介绍传送门
相关的代码地址 或者在android的代码目录下 \external\bsdiff
bsdiff是二进制差分工具,其对应的bspatch是相应的补丁合成工具
需要注意的是增量升级的补丁包,是需要在服务器端,即PC端完成,大致流程如,制作补丁时调用bsdiff函数,根据两个不同版本的二进制文件,生成补丁文件。
[html] view plaincopyprint?
命令:bsdiff oldfile newfile patchfile
例如: bsdiff xx_v1.0.apk xx_v2.0.apk xx.patch
将生成的补丁包 xx.patch放置在升级服务器上,供用户下载升级,对应多版本需要对不同的版本进行差分,对于版本跨度较大的,建议整包升级。
用户在下载了 xx.patch补丁包后,需要用到补丁所对应的apk,即原来系统安装的旧版本apk和补丁合成的bspatch工具。系统旧版本的apk可以通过copy系统data/app目录下的apk文件获取,而补丁合成的bspatch可以通过将bspatch源码稍作修改,封装成一个so库,供手机端调用。
[html] view plaincopyprint?
bspatch的命令格式为:
bspatch oldfile newfile patchfile
和差分时的参数一样。合成新的apk便可以用于安装。
以上只是简单的操作原理,增量升级还涉及很多其他方面,例如,升级补丁校验等问题,可以参考android源码中bootable\recovery\applypatch的相关操作,本文只是浅析,在此不表。
增量升级的不足
增量升级并非完美无缺的升级方式,至少存在以下两点不足:
1.增量升级是以两个应用版本之间的差异来生成补丁的,你无法保证用户每次的及时升级到最新,所以你必须对你所发布的每一个版本都和最新的版本作差分,以便使所有版本的用户都可以差分升级,这样操作相对于原来的整包升级较为繁琐,不过可以通过自动化的脚本批量生成。
2.增量升级成功的前提是,用户手机端必须有能够让你拷贝出来且与你服务器用于差分的版本一致的apk,这样就存在,例如,系统内置的apk无法获取到,无法进行增量升级;对于某些与你差分版本一致,但是内容有过修改的(比如破解版apk),这样也是无法进行增量升级的,为了防止合成补丁错误,最好在补丁合成前对旧版本的apk进行sha1sum校验,保证基础包的一致性。
增量升级的改善
现在有一项新的APP更新技术已经开始应用于手游更新,手游CP将更新包上传都CDN服务器,游戏就能在玩家玩游戏过程当中完成静默更新,整个过程玩家毫无察觉,保证玩家的手游什么时候都是最新版的。
云计算(cloud computing)是基于互联网的相关服务的增加、使用和交付模式,通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源。云是网络、互联网的一种比喻说法。过去在图中往往用云来表示电信网,后来也用来表示互联网和底层基础设施的抽象。
手游云更新是将CP提供的apk原包上传到云服务器上,经过云服务器处理后,将全新的apk包投放到渠道上,同时通过云服务器的高效、快速传输、智能的处理方式,将apk的更新包、更新资源实现智能云更新:减少用户流失,节省CDN开支,避免出现游戏版本更新中断或安装失败的稳定,保障稳定安全的透明更新无感知更新环境。
相比传统的手游更新方式,手游云更新有以下优势。
节约成本
1、省去渠道商务沟通环节,降低人力成本。
2、省去CP进行整包更新时上传渠道环节,云更新足以支撑大版本迭代。
3、非强制更新选择,可以让玩家在游戏过程中自动静默更新完成。
4、省去昂贵的CDN维护费用。
节约时间
1、省去打包环节,让开发从此告别频繁的接入SDK包。
2、接入云更新,即使全量更新也无需渠道配合,方便快捷一站完成。
3、省去停服维护时间,停服更新时间。
告别繁琐
1、告别繁琐的渠道-CP-发行配合流程,云更新后台帮你快速解决更新问题。
2、自主选择强制更新与非强制更新,非强制更新状态下,玩家不再纠结于更新界面,边玩变更,无缝对接新版本。
3、全面支持全量更新自动升级,不再反复安装游戏包,老玩家直接一键升级免安装。
服务器稳定
1、高性能的CDN服务器支撑,实现稳定更新。
2、用户体验感增强,有效减少用户在更新环节流失。
3、杜绝网络波动,实现快速更新。
4、爱加密游戏方案为您的版本保驾护航。
5、独有的破解分析和安全监测,让游戏告别后顾之忧。
目前,这项更新技术只是应用于手机游戏,但是我们可以预测这项技术将应用于其他APP。
爱加密(www.ijiami.cn)是国内顶尖的移动信息安全体系服务商,专注于为移动领域的金融、游戏、企业级应用及移动互联网开发者提供安全可靠的移动应用保护解决方案,服务范围覆盖Andriod和iOS两大主流智能手机系统。
目前,爱加密成功研发出了最新的压缩和云更新技术,将游戏包进行压缩,使得游戏安装包的内存减小,运行更加流畅。根据测试结果显示,该游戏包体压缩技术可将200M大小的游戏包体压缩至40M,并且对游戏品质毫无影响。再配以云更新技术,可让游戏在云端自动更新,在玩家操作过程中迅速完成余包体下载,完整体验游戏无需另行下载等待,使玩家体验起来更加流畅。
(文章转载于CSDN博客,爱加密改编)
下一篇: 预测:2016年将面对的六大移动安全威胁