思路
通过bsdiff库对new_apk和old_apk进行二进制对比,然后抽取差异化生成new_old.patch补丁包,然后app下载增量补丁包与old_apk合并,生成new_apk,然后安装替换,完成更新
工具
增量文件生成
这步放在服务器,主要生成各个老版本对新版本的增量补丁包patch,以及对新版本生成md5值,到时候下发给app补丁包以及md5值用于验证合成是否正确
(主要通过JAVA JNI调用bsdiff编译的.dll或者.so库文件)
增量文件合成
用android stuido2.2进行NDK开发
android stuido2.2 NDK环境配置了解cmake相关知识,as 2.2是通过cmake进行编译
cmake教程通过NDK生成.so库
1.将bspatch.c文件拷贝到cpp目录,新建bzip目录将bzip库的.c .h文件拷贝进去如下:
2.然后配置cmake的CMakeList.txt文件,这个文件as已经生成好了,添加如下:
aux_source_directory (src/main/cpp/bzip BZIP_SRC) # 将当前目录(不包含子目录)下所有源文件保存在变量 BZIP_SRC 中
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).
# Associated headers in the same location as their source
# file are automatically included.
src/main/cpp/bspatch.c
src/main/cpp/cn_qh_dn_patch_PatchUtils.h
${BZIP_SRC})
3.Java方面的调用代码如下:
public class PatchUtils {
static {
System.loadLibrary("bsdiff");
}
/**
* 合成补丁包
* @param oapk 当前版本的apk位置
* @param patch 补丁文件位置
* @param napk 新apk存放位置
* @return 0代表成功
*/
public static native int patchNewApk(String oapk, String patch, String napk);
}
通过javac javah生成 xx_xx_xx_PatchUtils.h头文件
4.修改bspatch.c文件,添加我们生成的头文件定义函数:
jint JNICALL Java_cn_qh_dn_patch_PatchUtils_patchNewApk
(JNIEnv *env, jclass cls, jstring oapk, jstring patch, jstring napk) {
int argc = 4;
char * argv[argc];
argv[0] = "bspatch";
argv[1] = (char *) ((*env)->GetStringUTFChars(env, oapk, 0));
argv[2] = (char *) ((*env)->GetStringUTFChars(env, napk, 0));
argv[3] = (char *) ((*env)->GetStringUTFChars(env, patch, 0));
int result = patchFile(argc, argv);
(*env)->ReleaseStringChars(env, oapk, argv[1]);
(*env)->ReleaseStringChars(env, napk, argv[2]);
(*env)->ReleaseStringChars(env, patch, argv[3]);
return result;
}
bspatch原来的函数名是main,改成了patchFile(),然后通过我们生成的JNI函数进行调用
4.make工程生成.so库
这里会报错误,显示很多main函数定义,类似这样的错误:
Error:(70) multiple definition of `main'
去掉bzip库文件的写了main函数的地方,再进行编译即可
5.在app中写代码进行下载apk.patch包和md5值,进行合并:
/**
* 合并补丁,生成新版本apk
* @param ctx
* @param patch_path 补丁包的文件路径
* @param napk_path 生成新包的存放路径
* @throws Exception
*/
public static void patch(Context ctx, String patch_path, String napk_path) throws Exception{
String oapk_apk = ctx.getApplicationContext().getApplicationInfo().sourceDir;
int result = PatchUtils.patchNewApk(oapk_apk, patch_path, napk_path);
Log.i("ApkUtils", String.format("result [%d]", result));
if(result != 0)throw new IllegalStateException("发生错误");
}
6.生成的apk进行安装即可