gagapencil学习小站

增量更新

字数统计: 1.1k阅读时长: 4 min
2019/06/20 Share

增量更新

增量更新 一种不需要重新下载apk,利用新的apk在原有的基础生成patch包进行更新的一种技术。本文重增量更新的作用,原理和使用进行阐述。

原理及作用

增量更新就是比较两个apk之间的二进制差异,生成patch包然后打入旧的apk里面从而达到生成新的apk。例如说:第一个版本是3M的apk ,第二个是8M的apk ,生成的patch包可能就在4M左右,甚至更小,但也不是单纯的两个apk相减的差值,有可能两个大小差不多的apk,生成patch包可能在1M左右,这个也是看包里的改动大小。生成的 patch下载到Android设备上跟较低版本的apk合成一个新版本的apk文件,如果不出意外的话,这个生成的apk和你之前做差分的apk是一致的。这么做就会为用户去节省很多的流量,就不会让用户去下载完整的apk,从而提高了用户体验。

使用

  1. 利用old.apk和new.apk生成增量文件(patch)
  2. 利用old.apk和patch生成new.apk
  3. 安装

需要实现增量更新,现在有各种开源的制作与合并差分包的开源库,比如:bsdiff、hdiff等等。因此我们只需要获得源码来使用即可。

增量文件的生成

这里利用bsdiff工具做二进制的一个diff和patch了,可以直接下载工具

window:https://github.com/cnSchwarzer/bsdiff-win/releases

ubuntu:ubuntu sudo apt-get install bsdiff

bisdiff算法原理

尽可能多的利用old文件中已有的内容看,尽可能少的加入新的内容来构建new文件。通常的做法是对old文件和new文件做子字符串匹配或者使用hash技术,提取公共部分,将new文件中剩余的部分打包成patch包,在patch阶段中,用copying和insertion两个基本操作即可将old文件和patch包合成new文件。

ubuntu编译bisdiff

下载

ubuntu可自己编译bsdiff工具,先下载bisdiff和bzip2

bsdiff 下载地址:

http://www.daemonology.net/bsdiff/

bsdiff 依赖bzip2(zip压缩库)

https://nchc.dl.sourceforge.net/project/gnuwin32/bzip2/1.0.5/bzip2-1.0.5-src.zip

下载完后解压

bsdiff: 比较两个文件的二进制数据,生成差分包

bspatch: 合并旧的文件与差分包,生成新文件
很显然,bspatch我们需要在Android环境下来执行,而bsdiff 一般会在你的存储服务器当中执行即电脑环境下执行(win或linux)

编译

我们在目录下 直接 make 会产生错误需要修改makefile:

1
2
3
4
5
6
7
8
9
10
11
12
13
install:
${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin
.ifndef WITHOUT_MAN
${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1
.endif
#上面这段makefile片段显然有问题(指令必须以tab开头)
#因此需要修改为:
install:
${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin
.ifndef WITHOUT_MAN
${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1
.endif
#也就是在 `.if` 和 `.endif` 前加一个 tab

修改后再来执行make 如果出现找不到bzip2 no file found bzlib.h之类的错误,则需要先安装bzip2:

Ubuntu:

install libbz2-dev ```
1
2
3
4
>
> Centos:
>
> ```yum -y install bzip2-devel.x86_64

Mac:

install bzip2```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>
> <!--install 不知道填什么,可以使用包管理器进行搜索: -->
>
> <!-- apt/yum/brew search bzip2 -->

如果执行make出现

```shell
bsdiff.c:(.text.startup+0x2aa): undefined reference to `BZ2_bzWriteOpen'
bsdiff.c:(.text.startup+0xcfa): undefined reference to `BZ2_bzWrite'
bsdiff.c:(.text.startup+0xe37): undefined reference to `BZ2_bzWrite'
bsdiff.c:(.text.startup+0xf80): undefined reference to `BZ2_bzWrite'
bsdiff.c:(.text.startup+0xfe1): undefined reference to `BZ2_bzWriteClose'
bsdiff.c:(.text.startup+0x1034): undefined reference to `BZ2_bzWriteOpen'
bsdiff.c:(.text.startup+0x105c): undefined reference to `BZ2_bzWrite'
bsdiff.c:(.text.startup+0x1082): undefined reference to `BZ2_bzWriteClose'
bsdiff.c:(.text.startup+0x10d5): undefined reference to `BZ2_bzWriteOpen'
bsdiff.c:(.text.startup+0x1100): undefined reference to `BZ2_bzWrite'
bsdiff.c:(.text.startup+0x1126): undefined reference to `BZ2_bzWriteClose'

则修改Makefile为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CFLAGS          +=      -O3 -lbz2

PREFIX ?= /usr/local
INSTALL_PROGRAM ?= ${INSTALL} -c -s -m 555
INSTALL_MAN ?= ${INSTALL} -c -m 444

all: bsdiff bspatch
bsdiff: bsdiff.c
cc bsdiff.c ${CFLAGS} -o bsdiff #增加
bspatch: bspatch.c
cc bspatch.c ${CFLAGS} -o bspatch #增加

install:
${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin
.ifndef WITHOUT_MAN
${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1
.endif

bsdiff可以通过如上编译使用,而bspatch则需要在Android工程中使用NDK来进行编译使用,工程地址:

https://github.com/HesitationPencil/Study/tree/master/bsdiffdemo

CATALOG
  1. 1. 增量更新
    1. 1.1. 原理及作用
    2. 1.2. 使用
      1. 1.2.1. 增量文件的生成
        1. 1.2.1.1. bisdiff算法原理
        2. 1.2.1.2. ubuntu编译bisdiff
          1. 1.2.1.2.1. 下载
          2. 1.2.1.2.2. 编译