前言

虽然jni.h中定义了很多函数,但也不是每个都需要用,这个主要是看需求。今天介绍一下常用jni函数,方便自己后续查阅。

正文

每个个函数可通过JNIEnv指针以固定偏移量进行访问。JNIEnv指针可指向存储全部JNI函数指针的结构。

如果要看全部的函数定义,可以看《NDK中jni.h头文件完整内容》,这里只介绍常用的函数。

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。

存在如下异常:

  1. ClassFormatError:如果class内容不是一个有效的class文件。

  2. ClassCircularityError:如果class或interface是它自己的父类或父接口,造成循环层级关系。

  3. OutOfMemoryError:如果系统在载入的过程中内存不足

  4. NoClassDefFoundError`:如果指定的类或接口没有被找到。

GetSuperclass

jclass      (*GetSuperclass)(JNIEnv* env, jclass clazz);
  1. 如果clazz代表类而非类object,则该函数返回由clazz所指定的类的超类。

  2. 如果clazz指定类object或代表某个接口,则该函数返回 NULL 。

至于第二个参数表示clazz还是object的,可以看《JNI之函数的参数介绍》这篇。

这里总结一下,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吧。多谢

参考文章

  1. JNI完全手册]》

  2. NDK中jni.h头文件完整内容

  3. JNI技术规范 – 第四章 JNI函数(1)》(后面几个函数的主要来源)

相关文章

暂无评论

none
暂无评论...