上一篇博客中,已经通过VS把bsdiff源码编译成了.exe的可执行文件,为了更好地给第三方语言调用,现在准备把bsdiff编译成.dll动态库,这样很多语言都可以顺利方便的使用了,这里以Java调用为例:

设计思路如下:

        既然bsdiff是c和c++写的,我们又需要在Java中调用,所以就可以在Java中声明一个本地方法,把旧文件、新文件和差分文件以参数的形式传到bsdiff.cpp的main函数中。因此就会在bsdiff.cpp中实现一个Java的方法,然后在方法中调用main方法,最终实现差分功能。那么开始动手吧。

一、用idea(也可用eclipse等)创建一个java项目,并创建一个包含native方法的类BsDiffYwl5320Util.java。

1.1、项目BsDiffYwl5320目录结构如下:

java全量包和增量包 增量jar包_Android

 

1.2、编译项目生成.class文件,并用命令javah把native方法生成相应的.h文件,如图:

java全量包和增量包 增量jar包_Android_02

 

二、编译dll动态库

2.1、把第一步里面的.h头文件移动到VS项目中的include里面,并添加到头文件里面:

java全量包和增量包 增量jar包_java全量包和增量包_03

 

2.2、这是打开文件com_ywl5320_bsdiff_BsDiffYwl5320Util.h为提示找不到jni.h头文件,所以我们还需要到windows的java目录下把相应的jni.h也添加到项目中,由于jni.h里面引用了jni_md.h头文件,所以需要把这两个头文件都复制到项目中才行:

2.2.1、jni.h和jni_md.h的位置如下

java全量包和增量包 增量jar包_bzip2_04

java全量包和增量包 增量jar包_BsDiff_05

 

2.2.2、复制到VS项目中后目录如下

java全量包和增量包 增量jar包_增量更新_06

 

三、在bsdiff.cpp中实现java中的native方法

3.1、导入.h文件,并在文件末尾实现方法,因为main函数有特殊用处,最好不要直接用main方法,这里把main方法改成了bsdiff_main: 

JNIEXPORT jint JNICALL Java_com_ywl5320_bsdiff_BsDiffYwl5320Util_bsDiffFile
(JNIEnv *env, jobject jobj, jstring joldfile, jstring jnewfile, jstring jpatchfile)
{
	int restlt = -1;
	int argc = 4;
	char *argv[4];

	char *oldPath = (char*)env->GetStringUTFChars(joldfile, NULL);
	char *newpath = (char*)env->GetStringUTFChars(jnewfile, NULL);
	char *patchPath = (char*)env->GetStringUTFChars(jpatchfile, NULL);
	argv[0] = "bsdiff_ywl5320";
	argv[1] = oldPath;
	argv[2] = newpath;
	argv[3] = patchPath;

	restlt = bsdiff_main(argc, argv);

	env->ReleaseStringUTFChars(joldfile, oldPath);
	env->ReleaseStringUTFChars(jnewfile, newpath);
	env->ReleaseStringUTFChars(jpatchfile, patchPath);
	return restlt;
}

 

 

3.2、添加64位平台,如下:

java全量包和增量包 增量jar包_BsDiff_07

java全量包和增量包 增量jar包_java全量包和增量包_08

java全量包和增量包 增量jar包_Android_09

java全量包和增量包 增量jar包_BsDiff_10

 

3.3、由于更改了编译平台,所以前面的include、SDL编译检查等还得重新配置一下,这里就不讲了,步骤可以看上一篇博客。

3.4、更改生成类型由.exe改成.dll:

java全量包和增量包 增量jar包_BsDiff_11

 

3.5、最后编译生成我们需要的.dll动态库:

java全量包和增量包 增量jar包_Android_12

java全量包和增量包 增量jar包_Android_13

java全量包和增量包 增量jar包_增量更新_14

这样就生成了我们需要的BsDiffYwl5320.dll动态库了。

 

四、Java中调用BsDiffYwl5320.dll库实现分包:

4.1、复制动态库和测试apk到项目根目录下

java全量包和增量包 增量jar包_Android_15

 

4.2、加载动态库 

package com.ywl5320.bsdiff;

/**
 * Created by ywl on 2017-10-23.
 */
public class BsDiffYwl5320Util {

    private static BsDiffYwl5320Util instance = new BsDiffYwl5320Util();

    public BsDiffYwl5320Util(){}

    public static BsDiffYwl5320Util getInstance()
    {
        return instance;
    }

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


    public native int bsDiffFile(String oldFile, String newFile, String patchFile);

}

  

4.3、调用native方法测试

java全量包和增量包 增量jar包_增量更新_16

成功生成了.patch包

 

4.4、为了获取执行状态,所以把bsdiff.cpp里面的错误方法改成带返回值的,并去掉里面的退出语句exit() 

template<class T>
int err(int i, const char* str, T arg) {
	printf(str, arg);
	return i;
}
int err(int i, const char* str) {
	printf(str);
	return i;
}
template<class T>
int errx(int i, const char* str, T arg) {
	printf(str, arg);
	return i;
}
int errx(int i, const char* str) {
	printf("%s",str);
	return i;
}

 

 

4.5、打包jar包,方便调用

java全量包和增量包 增量jar包_BsDiff_17

 

4.6、以jar方式调用dll差分测试:

java全量包和增量包 增量jar包_增量更新_18

 

测试成功,这样在Windows平台上面就完成了apk的差分,可以直接用到服务器差分里面。不管你是客户端工程师还是服务器端工程师,通过本篇文章都能自己实现apk的差分,是不是感觉自己棒棒的,哈哈。

下一篇文章介绍Linux(Ubuntu)平台上面生成差分包,毕竟Linux服务器是主流。

 

源码下载:GitHub BsDiffYwl5320