虽然jni.h中定义了很多函数,但也不是每个都需要用,这个主要是看需求。今天介绍一下常用jni函数,方便自己后续查阅。
正文
每个个函数可通过JNIEnv指针以固定偏移量进行访问。JNIEnv指针可指向存储全部JNI函数指针的结构。
如果要看全部的函数定义,可以看《》,这里只介绍常用的函数。
GetVersion
返回本地方法接口的版本。
jint (*GetVersion)(JNIEnv *env);
仅一个参数,env是jni接口指针。
在C++中调用更简洁些,后续都以C++方法调用,不重复解释了。
jint version = env->GetVersion(); #打印十六进制 LOGE("GetVersion:%#x", version);
输出
GetVersion:0x10006
16 位返回主版本号,低 16 位返回次版本号
我这用的是jdk1.6。
FindClass
jclass (*FindClass)(JNIEnv* env, const char* name);
该函数用于加载本地定义的类。搜索在由环境变量 CLASSPATH
目录下的子目录和zip文件中搜索指定的类名。
只关注第二个参数name,类全名 ,即包名后跟类名,之间由“ /” 分隔。如果名称以“ [” ( 数组签名字符)打头,则返回一个数组类 。
举些例子:
# String 的类全名(java.lang.String) name = "Ljava/lang/String" # Object[] 的类全名 name = "[Ljava/lang/Object;" # 自定义Hello类 name = "com/biumall/dynamic/one/Hello"
如果存在,返回指定名称的类的对象,否则返回NULL。
存在如下异常:
-
ClassFormatError
:如果class内容不是一个有效的class文件。
-
ClassCircularityError
:如果class或interface是它自己的父类或父接口,造成循环层级关系。
-
OutOfMemoryError
:如果系统在载入的过程中内存不足
-
NoClassDefFoundError`:如果指定的类或接口没有被找到。
GetSuperclass
jclass (*GetSuperclass)(JNIEnv* env, jclass clazz);
-
如果clazz代表类而非类object,则该函数返回由clazz所指定的类的超类。
-
如果clazz指定类object或代表某个接口,则该函数返回 NULL 。
至于第二个参数表示clazz还是object的,可以看《》这篇。
这里总结一下,clazz在静态函数时是jcalss,非静态时是jobject。
IsAssignableFrom
jboolean (*IsAssignableFrom)(JNIEnv* env, jclass clazz1, jclass clazz2);
判断clazz1的对象是否可安全地强制转换为clazz2。
如果是以下情况则返回 JNI_TRUE
:
-
clazz1 和 clazz2 指向同一个java类
-
clazz1 是 clazz2 的子类。(向上转型是安全的)
-
clazz1 是 clazz2(接口)的实现类。(也属于向上转型)
Throw
jint Throw(JNIEnv *env, jthrowable obj);
触发一个 java.lang.Throwable
对象的异常被抛出。obj是java.lang.Throwable对象。
成功则返回0, 失败时返回负数。
抛出 java.lang.Throwable
对象。
jthrowable exception = env->ExceptionOccurred(); if (exception) { env->ExceptionClear(); detach_internal(env, this_obj); env->Throw(exception); return; }
ThrowNew
jint ThrowNew(JNIEnv *env, jclass clazz, const char *message);
Exception对象的构造器函数,message为异常的错误消息,clazz为异常的类。
clazz为java.lang.Throwable的子类。
message用于创建 java.lang.Throwable 对象时传入的错误消息。这个是字符串是UTF-8编码。
成功则返回0, 失败时返回负值。并抛出刚构造出来的 java.lang.Throwable对象。
env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
其他的暂时不记录了,主要没常用。请看参考文3吧。多谢
参考文章
-
《]》
-
《》
-
《》(后面几个函数的主要来源)