关于JNI的理解
在android的平台上,JNI(Java native interface)是连接Java层和native层的一座桥梁。其实就是说JNI是Java调用native方法的一个“接口”。
JNI 可以这样与本地程序进行交互:
(1) 你可以使用 JNI来实现“本地方法”( native methods ),并在 JAVA 程序中调用它们。
(2 ) JNI 支持一个“调用接口”( invocation interface),它允许你把一个 JVM 嵌入到本地程序中。本地程序可以链接一个实现了 JVM的本地库,然后使用“调用接口”执行 JAVA 语言编写的软件模块。例如,一个用 C语言写的浏览器可以在一个嵌入式 JVM 上面执行从网上下载下来的 applets。
图一 JNI的工作流程
JNI层对应的库是lib****_jin.so, native层对应的库命名为lib****.so,其中两者的****是保持一致的。Java层通过lib****_jin.so实现跟lib****.so的交互。
Java层使用JNI很方便,可以直接加载JNI库,即在程序中添加一条加载语句即可。
例如:
Static{
System.LoadLibrary(“media_jni”);
}
同时,在Java程序中使用关键字native声明函数,此时表示调用的是native的方法。
2. JNI的注册问题。
一般情况下JNI的注册有两种:静态的方法和动态注册。
(1)静态方法如下图所示:
图 2 JNI静态注册方法
本质是:当Java层调用一个native_method函数的时候,它会首先从对应的JNI库中寻找这个java_android_****_****_method函数,如果没有就会报错。如果找到了就会为这个native_method和java_android_****_****_method建立一个关联关系,其实就是保存JNI层函数的指针。以后再调用native_method函数的时候,直接使用这个函数指针就可以了,当然这项工作是由虚拟机完成的。
(2)JNI的动态注册
动态注册的方式主要是实现这个JNINativeMethod的结构。在这个结构中,可以把java native函数和JNI函数一一对应起来。
描述这个结构体:typedef struct{
//Java中native的函数名
Const char* name;
//Java函数的签名信息,用字符串表示,是参数类型和返回值类型组合
Const char* signature;
//JNI层对应函数的函数指针,都是(void*)类型。
Void* fnPtr;
}JNINativeMethod;
其中,这个参数2,就是写法问题:
其中比较难以理解的是第二个参数,例如<