美文网首页
JNI开发快速入门总纳 [原创]

JNI开发快速入门总纳 [原创]

作者: 会跑步的石头 | 来源:发表于2018-01-09 11:14 被阅读0次

前言

•JNI——Java Native Interface,它是Java平台的一个特性(并不是Android系统特有的)。

•其实主要是定义了一些JNI函数,让开发者可以通过调用这些函数实现Java代码调用C/C++的代码,C/C++的代码也可以调用Java的代码,这样就可以发挥各个语言的特点了。

做安卓有些年了,发现身边的很多人不熟悉C++的开发,所以本文仅进行总体的归纳,希望能帮到您。

C++调用Java的方法

GetFieldID是得到java类中的参数ID,GetMethodID得到java类中方法的ID,它们只能调用类中声明为 public的参数或方法。

使用如下:

jfieldID  topicFieldId  = env->GetFieldID(objectClass,"name", "Ljava/lang/String;");

jmethodID  getcName  =env->GetMethodID(objectClass,"getcatName","()Ljava/lang/String;");

第一参数是Java 类对象。第二个参数是参数(或方法名),第三个参数是该参数(或方法)的描述符。

JNI同时提供了大量的方法用于类型转换,以及其他获取java方法的接口如GetStaticMethodID等。

参考:https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

类型描述符

类型描述符

查看java方法描述符

Cat类定义

比如查看Cat类   进入到Cat所在目录 先用javac Cat.java进行编译

然后输入命令:Javap –s Cat

即可得到Cat方法 getCatName 的签名是()Ljava/lang/String,Cat类中的参数是private 所以它没有签名。

Java调用C++ 

1.Java中声明native函数

例如:

public class HelloWorld{

public native String HelloFromC() ;

        public native Stringhell_from_c() ;

}

2. 用javac编译这个代码

javac HelloWorld.java

生成--> HelloWorld.class

3. 用javah 编译class文件

javah HelloWorld

生成-> HelloWorld.h 【头文件中包含了C代码的方法名JNIEXPORTjstringJNICALL Java_HelloWorld_hello_1from_1c(JNIEnv *, jobject)】

C++回调java

回调处理需要将回调方法attach到java VM中,否则没有JNIEnv且会被android回收,并出现错误

AttachCurrentThread :

     将当前threaderattach到VM

      *****

     *****

     *****

DetachCurrentThread :

     从VM上释放,如果当前stack中存在java的方法调用,则无法被释放。

注意:如果不需要用的时候一定要DetachCurrentThread,否则线程无法正常退出。

参考:https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html

例如:

回调参考代码

异常处理

JNI没有像Java一样有try…catch…final这样的异常处理机制,面且在本地代码中调用某个JNI接口时如果发生了异常,后续的本地代码不会立即停止执行,而会继续往下执行后面的代码。

JNI中的异常处理:

•JNI中处理JNI异常

•JNI中处理并抛出新的异常给Java

异常发生后记得释放资源

参考:https://www.developer.com/java/data/exception-handling-in-jni.html

另外:默认android不打开C++的异常控制处理,需要设置APP_CPPFLAGS := -fexceptions -frtti 进行打开

JNI中处理JNI异常

异常处理之前,需要先调用ExceptionClear清空 pending

exception的异常信息。如:

JNI中处理JNI异常

JNI中处理JNI异常并抛出新的异常给Java

异常处理之前,需要先调用ExceptionClear清空 pending exception的异常信息,与上一种处理不同的是增加了抛出新的异常。如:

JNI中处理JNI异常并抛出新的异常给Java 

相关资料

Java Native Interface Specification:

https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

相关文章

网友评论

      本文标题:JNI开发快速入门总纳 [原创]

      本文链接:https://www.haomeiwen.com/subject/nmjwnxtx.html