@cxm-2016
2017-02-18T08:30:47.000000Z
字数 2281
阅读 2605
Android
版本:2
作者:陈小默
参考自:张鸿洋- Android 增量更新完全解析 是增量不是热修复
注意:这里下载的是源码,需要对其执行编译操作。
解压到相应的文件夹,然后在此文件夹执行make(或其他编译指令)操作。
如果此时编译失败,我们需要修改 Makefile 文件,将其中 install 块下的 .
开头的命令添加一个缩进,结果就是下面这个样子:
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
bspatch: bspatch.c
install:
${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin
.ifndef WITHOUT_MAN
${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1
.endif
然后,重新执行编译指令,如果执行成功,将会生成一个 bsdiff
文件。这个文件就是用来生成增量文件的工具。
如果以上过程失败,可以去下面的下载地址下载并编译工具:
该工具编译完成之后会生成两个工具文件,一个是用于计算差异并生成增量文件的bsdiff
,另一个是用来合并文件的bspacth
。
在这里我们使用命令来生成一个增量包,并使用命令合并增量包。
假设我们原来的文件是 qq-1.0.apk ,新版本安装包是qq-2.0.apk,那么我们可以执行下面的命令:
./bsdiff qq-1.0.apk qq-2.0.apk qq-1.0-to-2.0.patch
这样就生成了一个 qq-1.0-to-2.0.patch增量包。
那么合并的过程类似,仅仅是使用的工具不同而已:
./bspatch qq-1.0.apk qq-2.0.apk qq-1.0-to-2.0.patch
上面的示例在PC上使用命令将旧的安装包和增量包进行了合并。但是在实际应用场景上,我们需要在客户终端上执行最终的合并操作。
fun extract(ctx: Context): String {
val context = ctx.applicationContext
val applicationInfo = context.applicationInfo
val apkPath = applicationInfo.sourceDir
return apkPath
}
该过程需要先配置NDK环境,请参考NDK开发OpenGL ES 3.0(一)——OpenGL-ES 3.0介绍以及NDK环境搭建。
声明一个native方法:
class BsPatch{
// 其中的三个参数为三个文件的路径
external fun bspatch(oldApk: String, newApk :String, patch :String): Int
companion object {
init {
System.loadLibrary("bsdiff")
}
}
}
首先,把之前下载的bsdiff中的 bspatch.c 拷贝到 jni 文件夹下,然后在其中实现本地方法:
JNIEXPORT jint JNICALL Java_***_bspatch
(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 = patchMethod(argc, argv);
(*env)->ReleaseStringUTFChars(env, old, argv[1]);
(*env)->ReleaseStringUTFChars(env, new, argv[2]);
(*env)->ReleaseStringUTFChars(env, patch, argv[3]);
return ret;
}
注:patchMethod为 bspatch.c 文件中的 main 方法
此时 bspatch 依赖于另一个库 bzlib,所以我们需要先下载另一个库文件,并导入到我们的工程中。
下载地址:
我们将解压后的文件添加进 jni 文件夹,然后将 完善 CMakeList.txt 文件即可。注意编译时可能会报错,main函数重复定义:
Error:(70) multiple definition of `main'
我们只需要定位到这些main函数,然后直接删除即可。这样一来,一个增量更新的应用就完成了。