Android增量更新(二)-差分文件(Windows-part2)-dll动态库和jar包

703 阅读5分钟
原文链接: blog.csdn.net

目录:

        Android增量更新(一)-差分文件(Windows-part1)

        Android增量更新(二)-差分文件(Windows-part2)-dll动态库和jar包


        上一篇博客《Android增量更新(一)-差分文件(Windows-part1)》中,已经通过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目录结构如下:



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



二、编译dll动态库

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



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的位置如下




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



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

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

  1. JNIEXPORT jint JNICALL Java_com_ywl5320_bsdiff_BsDiffYwl5320Util_bsDiffFile  
  2. (JNIEnv *env, jobject jobj, jstring joldfile, jstring jnewfile, jstring jpatchfile)  
  3. {  
  4.     int restlt = -1;  
  5.     int argc = 4;  
  6.     char *argv[4];  
  7.   
  8.     char *oldPath = (char*)env->GetStringUTFChars(joldfile, NULL);  
  9.     char *newpath = (char*)env->GetStringUTFChars(jnewfile, NULL);  
  10.     char *patchPath = (char*)env->GetStringUTFChars(jpatchfile, NULL);  
  11.     argv[0] = "bsdiff_ywl5320";  
  12.     argv[1] = oldPath;  
  13.     argv[2] = newpath;  
  14.     argv[3] = patchPath;  
  15.   
  16.     restlt = bsdiff_main(argc, argv);  
  17.   
  18.     env->ReleaseStringUTFChars(joldfile, oldPath);  
  19.     env->ReleaseStringUTFChars(jnewfile, newpath);  
  20.     env->ReleaseStringUTFChars(jpatchfile, patchPath);  
  21.     return restlt;  
  22. }  
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位平台,如下:






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

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



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




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


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

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



4.2、加载动态库

  1. package com.ywl5320.bsdiff;  
  2.   
  3. /** 
  4.  * Created by ywl on 2017-10-23. 
  5.  */  
  6. public class BsDiffYwl5320Util {  
  7.   
  8.     private static BsDiffYwl5320Util instance = new BsDiffYwl5320Util();  
  9.   
  10.     public BsDiffYwl5320Util(){}  
  11.   
  12.     public static BsDiffYwl5320Util getInstance()  
  13.     {  
  14.         return instance;  
  15.     }  
  16.   
  17.     static  
  18.     {  
  19.         System.loadLibrary("BsDiffYwl5320");  
  20.     }  
  21.   
  22.   
  23.     public native int bsDiffFile(String oldFile, String newFile, String patchFile);  
  24.   
  25. }  
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方法测试


成功生成了.patch包


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

  1. template<class T>  
  2. int err(int i, const char* str, T arg) {  
  3.     printf(str, arg);  
  4.     return i;  
  5. }  
  6. int err(int i, const char* str) {  
  7.     printf(str);  
  8.     return i;  
  9. }  
  10. template<class T>  
  11. int errx(int i, const char* str, T arg) {  
  12.     printf(str, arg);  
  13.     return i;  
  14. }  
  15. int errx(int i, const char* str) {  
  16.     printf("%s",str);  
  17.     return i;  
  18. }  
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包,方便调用


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


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

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


源码下载:GitHub BsDiffYwl5320