JNI
- JNI基础
JNI基础
JNI,java native interface,即java本地接口,是java调用本地化方法的接口,是为java编写本地方法,为jvm嵌入本地应用程序的标准化接口。首要目标是在给定的平台上采用java通过JNI调用本地化方法,而本地化方法是二进制库文件的形式存放,Windows上本地化方法是dll库形式,Unix上是so形式。通过调用本地的库文件的内部的方法,使java可以实现和本地机器的紧密联系,调用系统级的各接口方法,JNI可以实现java与本地化方法的相互调用,即java与C/C++实现相互的调用,双向的调用。
native开发目前有两种编译方式,一种是传统的,比较早的gcc的编译方式,一种是近几年推出的cmake编译方式。只是管理代码的编译方式的区别,其他的差别不大。作为开发者,语法和调试功底才是关键。
步骤:
·java类中声明native修饰的方法;
·使用javac编译java文件,会生成一个class文件;
·使用javah class完整名,会生成一个h的头文件;
·使用C/C++实现h头文件里的本地方法,并生成动态链接库;
·将库文件拷贝到java工程目录下,运行java;
在java程序中,
首先要在类中声明所调用的库名称,如下的static代码块内loadLibrary。库的扩展名不用写,由系统自动判断。
其次,对要调用的方法做本地化声明,只声明不实现。
第三,编译java程序文件生成class文件,使用javah命令生成h头文件。
第四,对于这个头文件,C/C++需要做的,就是把各个方法具体实现,编译生成链接库文件。生成动态链接库。
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("native-lib");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// Example of a call to a native methodTextView tv = findViewById(R.id.sample_text);tv.setText(stringFromJNI());}/*** A native method that is implemented by the 'native-lib' native library,* which is packaged with this application.*/public native String stringFromJNI();public native String setStr(String str);public static native void getV();
}
native-lib.cpp
#include <jni.h>
#include <string>extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplicationdemo_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());
}extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myapplicationdemo_MainActivity_setStr(JNIEnv *env, jobject thiz, jstring str) {// TODO: implement setStr()
}extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplicationdemo_MainActivity_getV(JNIEnv *env, jclass clazz) {// TODO: implement getV()
}
JNIEXPORT,JNICALL是JNI关键字,表示该方法是要被JNI调用的。