Android 应用增量升级方案之实践篇

  1. 云栖社区>
  2. 博客>
  3. 正文

Android 应用增量升级方案之实践篇

雪梦科技 2016-08-24 17:19:42 浏览2780
展开阅读全文

作者:snowdream
Email:yanghui1986527#gmail.com
QQ 群: 529327615
原文地址:https://snowdream.github.io/blog/2016/08/23/android-incremental-update-solutions/

名词解释

全量升级

每次下载完整的新安装包,进行覆盖安装。

增量升级

将新安装包和已经安装的旧安装包进行比对,生成一个差分升级包(Patch包)。用户下载patch包后,和已经安装的旧安装包进行合并,生成新安装包,再进行覆盖安装。

背景

在早期的Android应用开发中,由于android应用普遍比较小,因此,普遍采用了全量升级方案。简单粗暴,却行之有效。
但是,随着Android的发展,Android应用功能越来越多,体积越来越大,再综合以下几个因素考虑,全量升级方案逐渐无法满足我们的需求。
1.在国内,随着2G,3G,4G的逐步演进,手机网络越来越快,但有一点事实仍然没有改变:流量很贵,非常不够用。(这个因素不适合WIFI用户和土豪用户)
beijingmobile
以北京移动为例,最基础套餐,5元30M流量。而最新的微信APK安装包35M。也就是说,如果你选了最基础套餐,你一个月内使用全量升级方案,升级一次微信,流量都不够用。
2.在敏捷开发大行其道的今天,开发者希望尽快将新开发的功能推送到用户面前,并及时得到用户的反馈。恨不能三天一小版,一周一大版。

综合以上因素,开发者必须为用户考虑:省流量,省流量,省流量。

显然,全量升级这种土豪做法已经不再适用,于是,增量升级应运而生。

增量升级原理

首先,两句话简单概括增量升级原理:
1.服务端通过比对最新升级包,和当前应用包,生成差分升级包;
2.客户端将差分升级包和当前应用包合并,生成最新升级包。

接下来,简单介绍下增量升级的原理:
1.首先,客户端获取当前应用的Version Code和应用APK文件的MD5值,发送给服务器;
2.服务器根据既定策略,给用户返回更新包信息。

  1. 通过MD5值没有查询到旧有APK应用信息,返回全量升级包网址,全量升级包MD5值;
  2. 需要返回patch包,但还没有生成patch包时,后台去生成patch包,并返回全量升级包网址,全量升级包MD5值;
  3. 需要返回patch包,并且已经生成patch包时,返回patch包网址,patch包MD5值,全量升级包网址,全量升级包MD5值;
  4. 不需要返回patch包,则返回全量升级包网址,全量升级包MD5值;

3.客户端根据返回信息进行更新操作。

  1. 如果只有全量升级包相关信息,则下载全量升级包,并在校验MD5值后,安装更新包;
  2. 如果有差分升级包(patch包),则下载差分升级包。校验差分升级包的MD5值。如果校验失败,走上面一个步骤。如果校验成功,则将差分升级包和当前版本的APK进行合并操作,生成新的应用包。校验新的应用包MD5值。校验通过,这安装这个生成的新应用包。如果校验失败,则走上面一个步骤。

以上只是简单介绍了增量升级的原理,实际应用中还需要细化,考虑更多的场景。

注意: 下载过程中,必须支持断点续传策略。防止网络不畅时,不断重试,造成的流量浪费。

增量升级方案

增量升级方案的核心就是使用Diff/Patch算法来对新旧APK进行diff/patch操作。
目前主流的Diff/Patch算法是bsdiff/bspatch,来自:http://www.daemonology.net/bsdiff/

另外,我了解到,国内有人开源了另外一种Diff/Patch算法,名字叫做HDiffPatch,来自:https://github.com/sisong/HDiffPatch

据说,比bsdiff/bspatch更高效呢?详见《HDiff1.0和BSDiff4.3的对比测试》

我将bsdiff/bspatch和HDiffPatch,使用jni封装成so库,供android调用。项目地址: https://github.com/snowdream/android-diffpatch
在封装HDiffPatch过程中遇到问题,得到作者@sisong的支持和帮助,在此表示感谢。

bsdiff/bspatch和HDiffPatch算法都是开源的,服务端可以根据源文件来进行编译集成。
这里我主要在Android客户端的角度,介绍下bsdiff/bspatch和HDiffPatch怎么使用。

BsDiffPatch

  1. 在build.gradle文件中自定义jnilib目录
sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}
  1. app/libs/armeabi-v7a/libbsdiffpatch.so 拷贝到你的工程对应目录下。
  2. app/src/main/java/com/github/snowdream/bsdiffpatchapp/src/main/java/com/github/snowdream/diffpatch 拷贝到你的工程对应目录下,包名和文件名都不能改变。
  3. 在Java文件中参考以下代码进行调用。
IDiffPatch bsDiffPatch = new BSDiffPatch();
bsDiffPatch.init(getApplicationContext()); 
//diff
bsDiffPatch.diff(oldFilePath, newFilePath, diffFilePath);
//patch
bsDiffPatch.patch(oldFilePath, diffFilePath, gennewFilePath);

HDiffPatch

  1. 在build.gradle文件中自定义jnilib目录
sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}
  1. app/libs/armeabi-v7a/libhdiffpatch.so 拷贝到你的工程对应目录下。
  2. app/src/main/java/com/github/snowdream/hdiffpatchapp/src/main/java/com/github/snowdream/diffpatch 拷贝到你的工程对应目录下,包名和文件名都不能改变。
  3. 在Java文件中参考以下代码进行调用。
IDiffPatch hDiffPatch = new HDiffPatch();
hDiffPatch.init(getApplicationContext()); 
//diff
hDiffPatch.diff(oldFilePath, newFilePath, diffFilePath);
//patch
hDiffPatch.patch(oldFilePath, diffFilePath, gennewFilePath);

BsDiffPatch vs HDiffPatch

这里我选择高德地图Android客户端的两个版本来进行测试。

  • 测试来源:http://www.autonavi.com/
  • 测试版本: Amap_Android_V7.7.4.2128_GuanWang.apk 和 Amap_Android_V7.3.0.2036_GuanWang.apk (注:版本跨度大,差异大)
  • 对比算法: BsDiffPatch vs HDiffPatch
  • 测试结果:(详见下图)

    1. BsDiffPatch生成的patch包稍小。
    2. 两者的diff操作都非常耗资源,耗时间,无法忍受。(当然diff操作一般在服务端进行)
    3. 两者的patch操作都比较快。通过大概五次测试,BsDiffPatch的patch操作需要13s左右,而HDiffPatch的patch操作仅仅需要1s左右。

以上结果仅供参考。

  • 测试结论:

    1. BsDiffPatch应用更广泛
    2. HDiffPatch看起来更高效

test

扩展

以上算是比较成熟的增量升级方案了,但是仔细想想,可能还存在一些问题:
1.由于多渠道,多版本造成非常多Patch包
2.bs diff/patch算法性能和内存开销太高
第一个问题可以通过服务器策略进行限制。比如,只有最新版5个版本内的升级采用增量升级,其他的仍然采用全量升级。
据说,还有一种更强大的算法,可以解决以上问题。大家有兴趣的话,可以自己去了解。
crsync-基于rsync rolling算法的文件增量更新.md

参考

  1. 友盟增量更新的原理是什么
  2. Android应用增量更新库(Smart App Updates)
  3. Android实现应用的增量更新升级
  4. https://github.com/smuyyh/IncrementallyUpdate
  5. 浅析android应用增量升级
  6. https://github.com/cundong/SmartAppUpdates
  7. crsync-基于rsync rolling算法的文件增量更新.md
  8. https://github.com/sisong/HDiffPatch
  9. http://www.daemonology.net/bsdiff/
  10. https://github.com/snowdream/android-diffpatch

网友评论

登录后评论
0/500
评论
雪梦科技
+ 关注