04.linux下进行diff差分

概述

上一次我们在window下通过bsdiff的win版实现了在window下的差分,但是一般我们差分都是放在服务器上进行的。所以这次我们要做的就是在服务器上生成.so库,并让项目运行在linux服务器上来实现差分。

需要准备:linux服务器一台,eclipse,bsdiff,bzip2

生成相应的.so库

1.在window的eclipse下新建web项目

编写native方法

public class PatchDiffUtil {
    /**
     * 拆分
     * @param oldApkPath 老apk的路径
     * @param newApkPath 新apk的路径
     * @param diffPath 差分后的文件路径
     */
    public native static void diff(String oldApkPath,String newApkPath,String diffPath);

}

2.生成相应的.h文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_gxl_util_PatchDiffUtil */

#ifndef _Included_com_gxl_util_PatchDiffUtil
#define _Included_com_gxl_util_PatchDiffUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_gxl_util_PatchDiffUtil
 * Method:    diff
 * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_gxl_util_PatchDiffUtil_diff
  (JNIEnv *, jclass, jstring, jstring, jstring);

#ifdef __cplusplus
}
#endif
#endif

3.下载bsdiff和bzip2

4.将相应的文件放到同一个文件夹

  1. 新建一个文件夹bsdiff_linux。

  2. 将bsdiff下的bsdiff.c赋值到bsdiff_linux下,然后将下载的bzip2下的所有.c和.h文件都复制到文件夹下。

  3. 将生成的com_gxl_util_PatchDiffUtil.h文件复制到文件夹下。

  4. 将jni.h赋值到文件夹下。需要注意:由于我们要在linux下编译生成.so文件,com_gxl_util_PatchDiffUtil.h依赖于jni.h,所以需要将找android源码下的jni.h,而不是找jdk下的jni.h文件。如我的jni.h在D:\android-ndk-r13b\platforms\android-12\arch-x86\usr\include下。
    这里写图片描述

5.修改文件

修改com_gxl_util_PatchDiffUtil.h中的jni.h的引用为

#include "jni.h"

修改bsdiff.c中的,bzlib.h的引用为#include "bzlib.h",然后添加com_gxl_util_PatchDiffUtil.h头文件的引用,并实现

//1.引入头文件
#include "com_gxl_util_PatchDiffUtil.h"
#include <sys/types.h>
//2.引入bzlib.h
#include "bzlib.h"
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

//3.将main方法修改为bsdiff_main
int bsdiff_main(int argc,char *argv[]){

}

//4.实现头文件中的函数
JNIEXPORT void JNICALL Java_com_gxl_util_PatchDiffUtil_diff
(JNIEnv * env, jclass cls, jstring old_apk_path_str, jstring new_apk_path_str, jstring patch_path_str){
    //将jstring转成char*
    char* old_apk_path=(char*)(*env)->GetStringUTFChars(env,old_apk_path_str,NULL);
    char* new_apk_path=(char*)(*env)->GetStringUTFChars(env,new_apk_path_str,NULL);
    char* patch_path=(char*)(*env)->GetStringUTFChars(env,patch_path_str,NULL);

    //bspatch_main的参数
    int argc=4;
    char * argv[4];
    argv[0]="bsdiff";
    argv[1]=old_apk_path;
    argv[2]=new_apk_path;
    argv[3]=patch_path;

    //调用bspatch的函数进行合并
    bsdiff_main(argc,argv);

    //释放
    (*env)->ReleaseStringUTFChars(env,old_apk_path_str,old_apk_path);
    (*env)->ReleaseStringUTFChars(env,new_apk_path_str,new_apk_path);
    (*env)->ReleaseStringUTFChars(env,patch_path_str,patch_path);
}

将bzip2.c中的main方法修改为bzip2_main

IntNative bzip2_main ( IntNative argc, Char *argv[] ){

}

5.编译生成.so库

将bsdiff_linux这个文件夹上传至服务器
这里写图片描述
使用cd命令切换到bsdiff_linux目录下,执行如下命令生成bsdiff.so库

gcc -fPIC -shared blocksort.c decompress.c bsdiff.c randtable.c bzip2.c huffman.c compress.c  bzlib.c crctable.c -o bsdiff.so

我试过了,不会发生错误,而且在服务器上生成的速度很快,有了如下文件则代表成功了。
这里写图片描述

将代码运行在服务器进行差分

1.将old.apk和new.apk上传至linux上

修改这两个文件的路径为linux上的路径

public class ContantLinux {
    public static final String old_apk_path = "/home/ubuntu/bsdiff_linux/ndk_03_update_old.apk";

    public static final String new_apk_path = "/home/ubuntu/bsdiff_linux/ndk_03_update_new.apk";

    public static final String patch_path = "/home/ubuntu/bsdiff_linux/apk.patch";
}

这里写图片描述

2.修改加载.so文件的路径为linux下的路径

要注意是load,不是loadLibrary,

static {
        //System.loadLibrary("ndk_patch_update");
        System.load("//home/ubuntu/bsdiff_linux/bsdiff.so");
    }

3.调用

public static void main(String[] args) {
        PatchDiffUtil.diff(ContantLinux.old_apk_path, ContantLinux.new_apk_path, ContantLinux.patch_path);
        System.out.println("拆分完毕!");
    }

项目如下
这里写图片描述
很容易

4.打包项目生成.jar包文件

项目–>右键Export–>
这里写图片描述
选中runnable jar file
这里写图片描述
选中第二个
这里写图片描述

4.将jar文件上传至linux

将bsdiff.jar上传至linux服务器
这里写图片描述

执行 java -jar bsdiff.jar 就可以生成相应的patch包
这里写图片描述

5.原理

如果面试时被问到是否研究过其中的源码,则根据下面的进行吹水
这里写图片描述


这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值