@cxm-2016
2017-02-18T00:30:47.000000Z
字数 2281
阅读 2996
Android
版本:2
作者:陈小默
参考自:张鸿洋- Android 增量更新完全解析 是增量不是热修复
注意:这里下载的是源码,需要对其执行编译操作。
解压到相应的文件夹,然后在此文件夹执行make(或其他编译指令)操作。
如果此时编译失败,我们需要修改 Makefile 文件,将其中 install 块下的 . 开头的命令添加一个缩进,结果就是下面这个样子:
CFLAGS += -O3 -lbz2PREFIX ?= /usr/localINSTALL_PROGRAM ?= ${INSTALL} -c -s -m 555INSTALL_MAN ?= ${INSTALL} -c -m 444all: bsdiff bspatchbsdiff: bsdiff.cbspatch: bspatch.cinstall:${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.applicationContextval applicationInfo = context.applicationInfoval apkPath = applicationInfo.sourceDirreturn apkPath}
该过程需要先配置NDK环境,请参考NDK开发OpenGL ES 3.0(一)——OpenGL-ES 3.0介绍以及NDK环境搭建。
声明一个native方法:
class BsPatch{// 其中的三个参数为三个文件的路径external fun bspatch(oldApk: String, newApk :String, patch :String): Intcompanion 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函数,然后直接删除即可。这样一来,一个增量更新的应用就完成了。
