前言
•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
网友评论