什么是JNI?它是干什么用的?
java JNI 的本意是java Native Interface(java 本地接口),它是为了方便java调用c/c++等代码。我们知道的java的优点是跨平台的,但是作为优点的同时,其在和本地交互的同时就出现了短板,java本地交互能力不够强大,于是java提供jni专门用于和本地代码的交互。
JNI的优点
扩展:JNI扩展了JVM能力,驱动开发,例如开发一个wifi驱动,可以将手机设置为无限路由;
高效: 本地代码效率高,游戏渲染,音频视频处理等方面使用JNI调用本地代码,C语言可以灵活操作内存;
复用: 在文件压缩算法 7zip开源代码库,机器视觉 OpenCV开放算法库等方面可以复用C平台上的代码,不必在开发一套完整的Java体系,避免重复发明轮子;
安全: 产品的核心技术一般也采用JNI开发,不易破解;
*
怎么实现JNI调用?
实现jni调用的话分为两种情况:
(1)无现有so库需要下载NDK生成so库。
(2) 现有的so库,直接调用。
[1] 无现有SO库
1.下载NDK
2.创建jni文件夹
直接上图:
创建之后在app\src\main 下会出现JNI文件夹。
3.创建JNI类
创建一个普通类文件
public class JNIUtil {
static
{
System.loadLibrary("JNITestSample");//名字注意,需要跟你的build.gradle ndk节点下面的名字一样
}
//jni接口需要用"native关键字来修饰"
public native String getWorld();
}
4.生成头文件
这里有两种方式我们只介绍比较简单,一劳永逸的方法:使用android stuido 工具。
File->Setting->Tools->External Tools->“+”进入页面
按照下面参数配置:
Program:$JDKPath$\bin\javah.exe
Parameters:-classpath . -jni -d $ModuleFileDir$\src\main\jni $FileClass$
Working directory:$ModuleFileDir$\src\main\Java
这样我们的javah 命令配置好了,可以使用了。
右键JNIUtils-external tool - javah
编译之后会出现以下文件:
编译出的头文件"com_xiaoyuan_jnitestsample_JNIUtil.h",不难发现头文件名是有原报名+类名组成 :
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_xiaoyuan_jnitestsample_JNIUtil */
#ifndef _Included_com_xiaoyuan_jnitestsample_JNIUtil
#define _Included_com_xiaoyuan_jnitestsample_JNIUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_xiaoyuan_jnitestsample_JNIUtil
* Method: getWorld
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_xiaoyuan_jnitestsample_JNIUtil_getWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
5.重写头文件,完成cpp文件
复制.h文件保存为.cpp文件,命名与头文件相同。
#include <com_xiaoyuan_jnitestsample_JNIUtil.h>
JNIEXPORT jstring JNICALL Java_com_xiaoyuan_jnitestsample_JNIUtil_getWorld(JNIEnv *env, jobject obj)
{
return env -> NewStringUTF("JNI 过程成功 ");
}
6.build文件配置
ndk {
moduleName "JNITestSample" //编译出so的名字与JNIUtils中的一致。
}
7.重新build
在JniTestSample-master\app\build\intermediates\jniLibs\debug下会有编译出来的so库。
8
[2]拥有现有SO库
直接将so库文件夹拷贝到libs文件下:
修改build文件
在build.gradle 中添加以下代码。
sourceSets.main{
jni.srcDirs = []
jniLibs.srcDir "src/main/libs"
}
结果验证
大功告成!
Demo地址:https://github.com/LiuShouChun/JNIDemo