android 增量更新算法,Android 增量更新的实现

本文详细介绍了如何在Android系统上实现增量更新,包括使用bsdiff库生成和应用补丁,以及在Android Studio中配置NDK环境。过程中遇到了编译问题,通过修改CMakeLists.txt和添加gradle.properties解决了。文章最后提到了增量更新的局限性和后续考虑,如服务端生成补丁和多版本支持。
摘要由CSDN通过智能技术生成

扯淡

最近闲来无事,学习了一下增量更新。

增量更新的概念就不扯了,有兴趣的看一下鸿洋大神的文章Android 增量更新完全解析 是增量不是热修复。

测试设备(Android 5.0系统)

Talk is cheap!废话不多说,接下来开始踩坑之路。

准备工具

bsdiff/bzip 密码: qdrb

下载 bzip 后解压把里面的 .c 和 .h 文件复制到项目 app/src/main/jni/ 下面

bsdiff 文件中的 bsdiff.c 和 bspatch.c 文件复制到项目 app/src/main/jni/ 下面

Android Studio 配置 NDK 环境 Android NDK 开发从 0 到 1

生成增量文件

写一个工具类 DiffUtil.java

static {

System.loadLibrary("bsdiff");

}

/**

* native 方法 比较路径为 oldPath 的 apk 与 newPath 的 apk 之间差异,并生成 patch 包,存储于 patchPath

*/

public static native int genDiff(String oldApkPath, String newApkPath, String patchPath);

生成头文件

在 Terminal 中进入到项目 ..app\src\main\java> 下输入 javah -d ../jni 包名.方法名

如: javah -d ../jni sj.updateplus_utils.DiffUtil

复制头文件中代码到 bsdiff.c 中,之后再添加如下代码

JNIEXPORT jint JNICALL Java_sj_updateplus_utils_DiffUtil_genDiff

(JNIEnv *env, jclass cls, jstring old, jstring new, jstring patch) {

int argc = 4;

char * argv[argc];

argv[0] = "bsdiff";

argv[1] = (char*) ((*env)->GetStringUTFChars(env, old, 0));

argv[2] = (char*) ((*env)->GetStringUTFChars(env, new, 0));

argv[3] = (char*) ((*env)->GetStringUTFChars(env, patch, 0));

printf("old apk = %s \n", argv[1]);

printf("new apk = %s \n", argv[2]);

printf("patch = %s \n", argv[3]);

int ret = diffMain(argc, argv);

printf("genDiff result = %d ", ret);

(*env)->ReleaseStringUTFChars(env, old, argv[1]);

(*env)->ReleaseStringUTFChars(env, new, argv[2]);

(*env)->ReleaseStringUTFChars(env, patch, argv[3]);

return ret;

}

bsdiff.c 中还需要修改的地方

//原代码:

int main(int argc, char *argv[]) {

...

}

//修改为:

int diffMain(int argc, char *argv[]) {

...

}

//原代码

#include

//修改为,可自定义

#include "bzip2/bzlib.h"

最后再进行编译运行,这期间可能遇到各种报错,哈哈,没关系,反正我也不知道怎么解决。(。‿。开玩笑,后面有踩坑经历)

增量文件和 oldApk 的合并

这个和增量文件的生成类似

写一个工具类 PatchUtil.java

static {

System.loadLibrary("bsdiff");

}

/**

* native 方法 合并旧 apk 和补丁 patch,生成新的 apk

* @param oldApkPath 旧apk文件路径

* @param newApkPath 合并生成的新 apk 保存路径

* @param patchPath 增量文件路径

* @return 合并结果: 0-成功 -其他失败

*/

public static native int mypatch(String oldApkPath, String newApkPath, String patchPath);`

生成头文件

同增量文件的生成里面一样

在 Terminal 中进入到项目 ..app\src\main\java> 下输入 javah -d ../jni 包名.方法名

如:javah -d ../jni sj.updateplus_utils.PatchUtil

复制头文件中代码到 bspatch.c 里添加以下代码

JNIEXPORT jint JNICALL Java_sj_updateplus_utils_PatchUtil_mypatch

(JNIEnv *env, jclass cls,

jstring old, jstring new, jstring patch) {

int argc = 4;

char *argv[argc];

argv[0] = "bspatch";

argv[1] = (char *) ((*env)->GetStringUTFChars(env, old, 0));

argv[2] = (char *) ((*env)->GetStringUTFChars(env, new, 0));

argv[3] = (char *) ((*env)->GetStringUTFChars(env, patch, 0));

int ret = patchMain(argc, argv);

(*env)->ReleaseStringUTFChars(env, old, argv[1]);

(*env)->ReleaseStringUTFChars(env, new, argv[2]);

(*env)->ReleaseStringUTFChars(env, patch, argv[3]);

return ret;

}

bspatch.c 中还需要修改的地方

//原代码

int main(int argc, char *argv[]) {

...

}

//修改为,可自定义

int patchMain(int argc, char *argv[]) {

...

}

//原代码:

#include

//修改为:

#include "bzip2/bzlib.h"

踩过的坑

编译缺少 xxx 文件

CMakeLists.txt 文件中添加以下代码

add_library( # Sets the name of the library.

bsdiff

# Sets the library as a shared library.

SHARED

# Provides a relative path to your source file(s).

src/main/jni/bzip2/blocksort.c

src/main/jni/bzip2/bzip2.c

src/main/jni/bzip2/bzip2recover.c

src/main/jni/bzip2/bzlib.c

src/main/jni/bzip2/compress.c

src/main/jni/bzip2/crctable.c

src/main/jni/bzip2/decompress.c

src/main/jni/bzip2/dlltest.c

src/main/jni/bzip2/huffman.c

src/main/jni/bzip2/mk251.c

src/main/jni/bzip2/randtable.c

src/main/jni/bzip2/spewG.c

src/main/jni/bzip2/unzcrash.c

src/main/jni/bsdiff.c

src/main/jni/bspatch.c )

CMakeLists.txt 中这两处地方要一致,可自定义

add_library( # Sets the name of the library.

bsdiff

... )

target_link_libraries( # Specifies the target library.

bsdiff

...)

可能需要添加

gradle.properties 文件

android.useDeprecatedNdk=true

进行 MD5 验证

这个步骤是为了检验合并生成的 apk 文件和我们要升级更新的 apk 文件是否一样

在 apk 文件目录下打开 cmd

输入命令行

//***.apk 为需要验证的 apk 文件名

certutil -hashfile ***.apk MD5

033abd821c68

image.png

写在最后

到这边增量更新操作基本就完成了。还有一些考虑不足之处。

当然这只是进行了增量文件的生成和新 apk 的合并,而且也只是在本地进行。其实呢,增量文件的生成最好在服务端进行,而且需要生成多个版本与最新版本的增量文件,才能保证各个版本的用户可以正常更新;更新完后还要安装等。

笔者这里是对其他 apk 的增量更新,如果是对本身 apk 的更新的话,还需要提取自身 apk 之类的,其他步骤可参照以上所写。

第一次写文章,还望各位指点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值