android JNI的一些方法见解
距离上一次写博客过去了 很久,中间想写个MVP+RXjava+Dagger+Retrofit,然后一直耽搁了我会很快补上的,最近项目要用到串口,学习了一会JNI,现在把简介写出来,如果有写的不对的地方,下方评论联系我。
什么是JNI,全称是Java Native Interface(Java 本地接口)
作用是java调用本地语言,那么什么是本地语言呢,通俗来说C语言,C++这些就是本地语言。最简单的一句话,就是java代码调用C或者C++的代码来运行。如果你会C语言或者C++,在这些语言中具体实现也都是调用方法,而调用方法通常是需要传输参数,和返回值的。JNI就是为解决这两个问题诞生的,
JNI流程
首先 我们可以在新建android项目的时候勾选 C++支持。这样就支持C语言和C++的调用
添加以后,我们的项目工程里面就会多出一个文件和文件夹
build.grade文件里面也会多出这个
在MainActivity文件里面 1 标注的是这个java文件要加载的类库,类库的就是C语言和C++编译的一种东西,libname “native-lib” 就是你在CMakeLists.txt的名称,这个”native-lib”是可以改的,但是要保证下面的1,3也要改成一样。
其中 1,3 是相同的 ,2 就是你要调用的C++文件路径
而在MainActivity中的 public native String stringFromJNI(); 就是本地方法用关键词native标识。对应下面的
Java_com_example_administrator_csdnjni_MainActivity_stringFromJNI
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_administrator_csdnjni_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
这是在java文件调用native方法的用法 和普通方法一样调用 ,这里强调一下 如果你定义的native 方法是静态的,那么你在下面生成头文件.h的时候,要注意这个
意思呢 就是你如果定义的native方法是动态 那么在头文件里面那个是Jclass,普通的就是jobect。 这个头文件 都是自动生成的,一般你不改 也不会 犯这样的错误。
现在就看完这个android的默认JNI了,你会发现没有头文件,而人家的代码都有的。。。。
android studio使用tool生成头文件
熟悉C语言的都知道头文件,我们可以使用命令生成,也可以借助android studio的工具。File | setting |Tools |EXternal
假如我想对一下这个路径的java文件生成,其带有的native方法。
L:\androidXiangMu\NOJni\app\src\main\java\android_serialport_api\SerialPort.java
1 是android studio 内置的javah位置 在内置的JDK下面,jdk10 已经取消,用javac -h。你也可以选择自己安装的JDK位置
2 -classpath \src\main\java //要生成类的前面地址 对应它 L:\androidXiangMu\NOJni\app\src\main\java
-jni
//要生成头文件的包名加类名 对应它 android_serialport_api\SerialPort.java
3是生成的头文件存放在那个位置**
‘$ModuleFileDi’ 这个是点击旁边Inert Macro 里面的
然后我们rebuild一下工程,右键选中你要选择生成带有native方法的java文件,然后 External Tools | javah 就在你上面3定义的那个位置 生成一个.h文件,名称很长 ,可以改。
JNI的静态注册和动态注册
静态注册就像android studio默认实现一样 都是Java_包名_ 类名 _ 方法名,然后在有native方法的那个java文件里面 加这句代码 就静态注册了
static {
System.loadLibrary("native-lib");
}
动态注册嘛就是用jni_onload方法。记住这个方法在本地代码里面 也就C语言或者C++ 然后可以参考这篇文章很不错的静态/动态注册 jni
上一篇: JS继承的一些见解
下一篇: Golang地图的一些见解
推荐阅读