之前写过一篇博客是:手把手教你在Android中使用bsdiff实现文件增量更新 。
由于Android Studio自带NDK的环境,所以实现JNI是比较简单的。
但是在博客中也说到了,文件差分的功能肯定是要在服务端进行的。而服务端运行的环境可能是在window,mac或者linux等。所以,我们需要把bsdiff的源码编译成对应环境需要的 native 库文件,以便于给Java调用。
由于大多数项目基本都是在linux上运行的,这里我就只演示下如何把bsdiff源码编译成so文件,然后在java代码中调用。
废话不多说,开始干!
Clion搭建编译环境
这里我使用的Jetbrains全家桶中的Clion. Jetbrains的IDE不用多说了,懂得都懂。
首先是需要准备一个Linux的系统,Windows的话本地调试推荐直接用WSL安装ubuntu。安装方式也比较简单,按照官方文档走即可。WSL安装文档:
如果是MAC的话,本地调试推荐使用docker去安装linux。在使用Docker作为Clion的编译环境时,一定要安装那种已经配置过cmake和gcc等编译环境的镜像,否则Clion识别不出来,我之前是先安装的ubuntu,然后再安装cmake,gdb等环境,结果Clion死活找不到,一直提示未找到安装包,在这个地方卡了快一天,给我整的都怀疑人生了。后来还是按照官方文档的方式才成功的,官方文档:Using Docker with CLion
jetbrains在github上也提供了几个写好的Dockerfile,自己根据需要选择即可。clion-remote
另外一种是比较推荐的方式,去阿里云购买一个云主机,直接远端编译,然后把写好的代码发布到远端进行测试,windows和mac都能用,比较方便。
安装完linux环境准备好之后需要安装cmake,gdb等,这里就不多BB了。安装后去Clion配置下工具链,根据自己需要配置,如下。
然后是配置cmake
至此环境就配置好了
在Linux上将C编译成so
在之前Android使用bsdiff的博客中,我们已经对bsdiff做了处理了,也能在Android上打出so。
那在java web项目中也是一样的步骤,准备java声明的native代码,更改cpp代码,配置cmake即可。
需要注意的是Android项目中的NDK可以直接引入jni.h,在Clion中我们要把需要手动把jdk中的jni.h和jni_md.h 拷贝到项目里,
jni.h在jdk中的includ目录里,jni_md.h在win32的目录里。
代码的结构如下
然后就可以去编译so文件了。点击build->Rebuild Project即可。
等待项目构建完成,如下
可以看到完成了,然后去上面红框给定的目录看一下文件。
可以看到,linux上是有源码的,相当于Clion把你本地的代码上传到linux中,然后通过linux的环境来进行编译了。
切到指定的最终目录看下
上面红框的so文件就是我们需要的了。
至此,linux上编译出so文件就搞定了。
Java Web Jni实现
然后就简单了,就是正常的JNi实现。先贴一下项目目录。
注意要加一下java代码访问resources目录中so文件的配置
下面是一些关键代码,这里只是demo代码,以实现功能为主,在生产环境下要注意下代码健壮性。
package com.yzq.bsdiffserver.utils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
/**
* @description: 用来load so文件,先将项目的so拷贝到linux中,然后加载
* @author : yuzhiqiang (zhiqiang.yu.xeon@gmail.com)
* @date : 2021/12/18
* @time : 14:33
*/
public class LibLoader {
public static void loadLib(String libName, String resourcePath) {
System.out.println("libName = " + libName);
System.out.println("resourcePath = " + resourcePath);
/*获取当前项目所在的linux路径 示例:/home/admin/weba