Android平台-实现应用增量更新

1.概述

1.1.什么是应用增量更新

当我们要更新一个应用的时候,以前很多更新的做法是下载一个新版本去覆盖一个旧版本。随着现在应用越来越大,我们就不得不考虑流量的问题。

Google也意识到不断更新应用对用户流量的损耗,于是在Google I/O上提及了增量升级,或者叫差分升级的方法,并在新版本的Google Play中得到支持。

简单的来说,增量更新是指在进行更新操作时,只更新需要改变的地方,不需要更新或者已经更新过的地方则不会重复更新,增量更新与完全更新相对。

1.2.增量更新原理

增量升级的原理其实不难,我们首先使用旧版本的apk与新版本的apk做差分,就能得到更新部分的补丁,也叫差分包。这个差分包虽然不是新旧版本的简单相减,但显而易见的是,用户不需要全部下载新版本apk了,我们只要下载更小的那个补丁包(差分包)。

在用户下载完差分包后,需要在手机端将它们组合起来。一般手机的应用安装在data/app下,我们可以复制出就版本apk至SD卡中,与下载好的差分包进行组合。最后得到一个新版本的apk后与服务器上的新版本进行校验,正确后就可以安装了。

2.环境搭建

2.1.NDK下载安装

NDK(native develop kits),是一个交叉编译的工具链。交叉编译是指:在一个平台下(CPU,操作系统)可以编译出在另外一个平台可以运行的代码,例如我们正要做的:windows AMD intel x86架构->手机android arm处理器。

下载地址:http://www.android-doc.com/tools/sdk/ndk/index.html

2.2.Cygwin安装

Cygwin是一个可以在windows下模拟出linux环境的一个工具,NDK必须在linux环境下进行编译等工作。

下载地址:http://www.cygwin.com

安装过程略。需要注意的是在Selectpackages安装界面中把Default改为Install,直接点击Default即可。

完成安装后,我们启动Cygwin,输入make  -v命令,出现如下信息说明安装成功了。

输入make  -v命令

我们cd到NDK的目录,执行./ndk-build命令,出现如下信息则说明大功告成。

执行./ndk-build命令

2.3.在Eclipse中或MyEclipse中安装CDT插件(可选)

将下载好的安装包解压,把features、plugins目录下的文件对应的复制到Eclipse(MyEclipse)中即可,重启软件。

3.实现过程

3.1.差分patch文件的生成

首先要生成旧版本和新版本的差分比patch文件,我们可以借助bsdiff开源库的windows版本。我们先下载bsdiff压缩包,解压后有以下两种工具。

解压bsdiff

Bsdiff.exe就是一个二进制差分工具,bspatch.exe就是相应的补丁合成工具了。我们的增量升级的差分包,是要在服务端完成的,也就是pc端去完成。我们打开命令行,转到bsdiff所在目录下,将新旧版本的apk也放到该目录下,执行命令:

bsdiff.exeoldName.apknewName.apkpatch.patch

Patch文件的名字可自己定义。如测试程序中的两个版本的apk。

测试

3.2.patch文件放至服务器

将生成的差分包xx.patch放置到升级服务器上,供用户下载升级。如果多版本,则必须对不同版本都进行差分。如果版本跨度太大,可以选择整包升级。

测试中将上一步生成的Update.patch包放在发布服务器Tomcat上。

3.3.Android合成新apk

3.3.1.编写本地方法

我们建一个Android工程,命名为UpdateDemo,用来实现应用增量更新功能。在工程中建一个包,编写本地方法。

编写方法

3.3.2.So文件的调用

我们首先用NDK编译出一个*.so文件。这个文件网上有编译好的,可以直接下载使用。附录中详述了如何去编译.so文件。

将下载好的.so文件放置于3.3.1新建的工程目录libs\armeabi文件夹下。

.so文件

我们现在就可以调用patch方法来合成新apk了。在主程序MainAcitivity类中加入以下代码,该代码就是调用我们所需的so库文件。

调用so库文件

这里得注意,我们的so文件前lib是系统生成加上去的,所以在调用中我们只需将名字去掉lib的名字作为参数。

3.3.3.配置XML

无论在下载还是合成删除中,我们都必须获取手机SD卡的读写权限,我们在UpdateDemo工程中AndroidManifest.xml加入以下代码。

AndroidManifest.xml

3.3.4.下载patch差分包

我们在UpdateDemo工程中加上添加一个更新按钮,实现点击按钮能够弹出下载选框,点击下载就可以下载服务器上的patch包了。我们设定下载的目录就是SD卡的跟目录。运行该程序,界面如图。

apk界面

我们点击更新按钮,如下。

更新

3.3.5.复制旧安装包

在合成过程中,我们需要旧安装包。在Android中非系统程序默认安装在data/app文件夹下,在非root情况下,我们可以对其本身安装包进行读操作,这样我们就可以将它复制到SD根目录下(和之前下载的patch文件同目录)。

在下载完成后,下载函数返回DOWN_OVER,线程接到这个信号后,调用PatchThread()函数。

主线程

我们在PatchThread()中调用复制旧安装包backupApplication(String packageName, String dest)方法。该方法第一个参数为安装包的ID号,如本例中的com.tutor.update,dest为复制目标路径。该方法中,主要函数如下。

backupApplication方法

该函数能够找到data/app下相应的安装包。

测试中我们下载完patch文件后,立刻复制旧安装包。

版本更新

我们用360助手查看SD中文件。

SD中文件

3.3.6.合成新apk

接下来就可以调用本地方法合成新apk了。

同样在PatchThread()函数中,当复制成功后,我们就可以调用如下方法了。

合并apk

参数都是旧、新和patch文件的路径。我们可以用360助手查看,新的apk已经合成,我们可以在程序中设定它的名字。这样,我们的新apk合成成功。

新apk合成成功

3.3.7.MD5校验

合成新apk后,我们无法预知它的正确性,在下载或在合成过程中,文件都有可能出错,所以紧接着我们需要对它进行MD5校验。

用MD5校验工具对服务器上的新apk进行校验,得到校验码。然后Android端合成新apk后对新apk也进行校验。我们在UpdateDemo工程中再建一个包,编写MD5类。

编写MD5

我们在MainAcitivity类中的PatchThread()函数中构造MD5对象,调用check方法即可。

用返回的校验值和服务器上的校验值对比,相同则进行安装,不同则提示校验失败。

校验失败

3.3.8.安装新apk

校验正确后自动安装即可。紧接着校验函数,我们加入判断,如果校验正确,则调用以下方法;如果错误,我们就跳出提示信息。

安装新apk

安装完成后打开软件,已经是V2版本了,我们增量更新成功。

量更新成功

3.3.9.删除残余文件

最后我们只要把用户下载的patch文件和旧apk删除即可,用户最终可以得到新apk,新apk用户可以自行处理。

删除时我们只要在安装后或在校验错误后调用delete()函数即可。

delete()函数

用助手查看SD目录,只有新apk了。

只有新apk

如果校验不通过,所有相关文件都会被删除。这样,我们就完成了我们的更新操作。

4.各种生成差分包大小列表

增量更新虽然不用将新apk的内容全部下载,但如果版本相差过大,或者apk本身非常小,还是建议下载整包。以下做了个小测试。

生成差分包大小列表

我们能够观察到,当apk不足1M时,差分包大小同样也有几百K,所以没必要去差分。当版本相差过大,增加内容非常多时,我们也建议直接整包更新。差分时包越大耗时越长。

5.附录

测试中我们用到网上已有的so库,直接调用即可。我们也可以自己在客户端生成so文件。

我们先下载bzip2-1.0.6.tar.gz。新建一个Android工程,将可能用到的下列文件复制到新建的Android工程的jni目录下(没有的新建一个目录)。

下载地址:http://www.bzip.org/downloads.html。

bzip2-1.0.6.tar.gz

5.1.Android.mk配置

在该jni目录下新建文件,命名Android.mk,配置如下。

Android.mk

5.2.方法实现

5.2.1.头文件生成

打开cmd命令行,转到工程目录的bin文件夹下,输入以下命令。

生成头文件

系统会自动生成一个.h文件,我们把它拷贝到jni目录下。

.h文件

5.2.2.编译成so库

我们在jni目录下新建com_example_jni_MainActivity.c,完成c代码。

com_example_jni_MainActivity.c

打开Cygwin,转到工程目录,使用ndk命令编译成so库即可。

编译成so库

我们可以看到libBSdiff.so已经编译成功,在lib/armeabi目录下。

libBSdiff.so

这样,我们就可以使用该so文件去合成新apk了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 在前几年,整体移动网络环境相比现在差很多,加之流量费用又相对较高,因此每当我们发布新版本的时候,一些用户升级并不是...
    涅槃1992阅读 5,462评论 2 39
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,438评论 25 707
  • @[增量更新,差分包,bsdiff/patch] 背景 随着Android app的不断迭代升级,功能越来越多,a...
    SunYo阅读 14,391评论 2 7
  • 经艳子姐介绍加入组织后,真真切切感受到笔友们对文字的喜爱,对写作的热情,不同年龄,不同职业,天南海北的人聚在一起,...
    半山桃源阅读 185评论 5 4
  • 为什么在一起 两个人选择在一起,可以是因为热恋的爱情,也可以不是因为难以自拔的爱。 试想,你...
    青糯君阅读 612评论 0 3