增量更新

前言

增量更新的主要目的是省流量。关于在哪个页面更新、到底提示不提示更新、是否强制更新等等这都不是增量更新的重点,这些根据具体需求就好了。增量更新主要就是用更少的流量去更新。

增量更新主要涉及两个操作:差分、合并。合并指的是当前版本与所对应的差分包进行合并,这个操作在客户端完成。差分指的是新版本与之前旧版本所产生差分包,这个操作在服务端完成。后台应该有上传apk的功能,比如上传3.0版本的apk,那么上传完就应该生成各种差分包,比如与2.0版本apk的差分包、与1.0版本apk的差分包。

新旧版本重复部分越多,差分包越小;重复部分越少,差分包越大。

我们这里增量更新使用BsDiff开源项目,这个项目本来又依赖bzip。官网

服务器端

编译BsDiff开源项目

  • 新建项目bsdiff,将源码中.c文件、.cpp文件、.h文件复制进该项目(\bsdiff\bsdiff)
  • 源文件–>添加–>现有项 (选择.c和.cpp文件)
  • 头文件–>添加–>现有项 (选择.h)
  • 删掉bsdiff.cpp文件
  • 编译报错
会提示使用了过时的方法以及不安全。在bsdiff.cpp里加入下面的宏定义。

#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_DEPRECATE

上面在这个文件写宏定义,如果好几个文件都用过,写起来就麻烦了。可以用下面方法:
右键项目-->属性-->配置属性-->c/c++ -->命令行-->其它选项
输入下面这句
-D _CRT_SECURE_NO_WARNINGS -D _CRT_NONSTDC_NO_DEPRECATE

接着编译。下面报错。
C4703	使用了可能未初始化的本地指针变量“old” 等等。
解决方法:右键项目-->属性-->配置属性-->c/c++ -->常规-->SDL检查 否

  • 生成动态库.dll的一些配置。(不再重复介绍,可见前面博客)
  • bsdiff.cpp的main函数我们就可以自己使用了,换个名字,改成bsdiff_main
  • 然后就是写Java层代码,写JNI,生成.dll库,Java层调用。步骤可见前面博客,代码见下文。主要代码如下:
JNIEXPORT void JNICALL Java_cn_gxh_update_server_BsDiff_diff
(JNIEnv *env, jclass jcls, jstring oldfile_jstr, jstring newfile_jstr, jstring patchfile_jstr) {
	int argc = 4;
	char* oldfile = (char*)env->GetStringUTFChars(oldfile_jstr, NULL);
	char* newfile = (char*)env->GetStringUTFChars(newfile_jstr, NULL);
	char* patchfile = (char*)env->GetStringUTFChars(patchfile_jstr, NULL);
	//参数,第一个参数无效
	char *argv[4];
	argv[0] = "bsdiff";
	//strcpy(argv[1],oldfile);
	//strcpy(argv[2], newfile);
	//strcpy(argv[3], patchfile);

	argv[1] = oldfile;
	argv[2] = newfile;
	argv[3] = patchfile;
	bsdiff_main(argc, argv);

	env->ReleaseStringUTFChars(oldfile_jstr, oldfile);
	env->ReleaseStringUTFChars(newfile_jstr, newfile);
	env->ReleaseStringUTFChars(patchfile_jstr, patchfile);
}

Windows服务器下产生差分包

上面我们已经生成了bsdiff.dll文件。下面是java层对用的代码:

package cn.gxh.update.server;

public class BsDiff {
	
	public native static void diff(String oldfile ,String newfile,String patchfile);

	
	static{
		System.loadLibrary("bsdiff");
	}
}

调用生成差分包:

//得到差分包
BsDiff.diff(ConstantsWin.OLD_APK_PATH,
		ConstantsWin.NEW_APK_PATH, ConstantsWin.PATCH_PATH);

客户端

客户端的主要工作是:下载、合并。下载的过程我们就不提了,反正下载的是.patch差分包。这里我们主要介绍是怎么合并的。

我们主要用到了bsdiff开源项目的bspatch.c文件,这里面有个main方法是来做合并的。(所以用的时候还是改革名字,改成bspatch_main吧)

这里也是NDK的开发流程,可以参考之前的博客,这里不多说了。贴一下主要的代码。值得一提的是,bspatch.c使用了bzip2的代码,所以需要把bzip2复制到jni目录下,改一下bspatch.c的相关文件的引入。

//java层代码:
package cn.gxh.update.util;

public class BsPatch {
	public native static void patch(String oldfile,String newfile,String patchfile);
	
	static{
		System.loadLibrary("bspatch");
	}
}
//这里编译的bspatch.c文件,合并的代码直接在这个文件里写的。
JNIEXPORT void JNICALL Java_cn_gxh_update_util_BsPatch_patch
  (JNIEnv *env, jclass jcls, jstring oldfile_jstr,
		  jstring newfile_jstr, jstring patchfile_jstr){
		int argc = 4;
		char* oldfile=(char*)(*env)->GetStringUTFChars(env,oldfile_jstr,NULL);
		char* newfile = (char*)(*env)->GetStringUTFChars(env,newfile_jstr, NULL);
		char* patchfile = (char*)(*env)->GetStringUTFChars(env,patchfile_jstr, NULL);
		//参数,第一个参数无效
		char *argv[4];
		argv[0] = "bspatch";
		argv[1] = oldfile;
		argv[2] = newfile;
		argv[3] = patchfile;
		bspatch_main(argc,argv);
		(*env)->ReleaseStringUTFChars(env,oldfile_jstr, oldfile);
		(*env)->ReleaseStringUTFChars(env,newfile_jstr, newfile);
		(*env)->ReleaseStringUTFChars(env,patchfile_jstr, patchfile);

}

说明

所有资料均可下载

若没有积分下载,可评论留下邮箱。。

你可能感兴趣的:(ndk笔记)