JNI 异常概述

JNI没有异常处理机制,也就是没有Java那一套 try-catch-finally。这样做,一方面是为功能,另一方面是因为在某些状况下,没有满意的运行时类型信息来供应异常检测。因而咱们有职责确保不运用空指针,不传入不合法参数。

可是,JNI供应了一android下载软件app系列的函数,用于检测是否有异常产生、抛出异常、清空异常。

处理异常

一般android下载JNI函数会经过回来值和抛出异常来陈述异常状况。因而通常咱们能够经过回来值来快速判别函数是否android11有异常产生。可是有些状况下,咱们有必要首要检测异常,因为咱们无数组的界说法得到回来值,这些状况有两种,如下

  1. 在native函数中调用Java办法,而Java办法可能会抛出异常。此时无法经过回来值判别是否有异常产生,只需检测是否java游戏产生了异常。
  2. JNI的数组操作不会回来一个过错的回来值,而是会抛出ArrayIndexOutOfBoundsExceptiandroid/yunoson或ArrayStoreException。因而也不能运用回来值来判别是否产生了异常,只需进行异常检测。

说了这么多,咱们怎样检测异常呢,有下面两种办法

jthrowab数组函数的使用办法le ExceptionOccurred(JNIEnv *env);
jboolean ExceptionCjava游戏heck(JNIEnv *env);

这两个函数都能够用来检测是否产生了异常,而它们的区别在于,函数调用能够ExceptionOccurreandroid手机d 函数会函数调用句子回来一个异常引用,而 ExceptionCheck 回来一个布尔值,用来标明是否有异常产生罢了。

现在咱们来用一个native函数android平板电脑多少钱调用Java办法为例,来阐明怎样检测异常。

现在这段native函数代码调用了java层的办法

JNIE源码交易网站源码XPORT void JNICALL
Java_com_example_helllojni_MainAandroid下载软件appctivity_helloFromJava(JNIEnv *env, jobject thiz, jobject person) {
jclass activity_clazz = env->GetObjectClass(thiz);
jmethodID methodID_setAgeFromJni = en源码v->GetMejavahdxxthodID(activity_c源码交易网站源码lazz, "setAgeFromJni", "(I)Z函数调用过程");
// 1. 经过Java层办法来检测并设置年岁
env->CallBooleanMethod(thiz, methodID_setAgeFromJni, 1);
// 2. 假定Java层判别年岁不合法会抛出异常,这儿需求检测处理,不然程序挂掉
if (env->ExceptionCheck()) {
// 首函数调用中的参数太多要必需求铲除异常,再调用其它函数进行异常补偿
env->ExceptionClear();
return;
}数组词
// 3. 走到这儿阐明方才设置年岁的操作合法了,现在来设置名字
jclass person_clazz = env->GetObjectClass(person);
jme函数调用中的参数太多thodID methodID_setName = env->GetMethodID(person_clazzjava游戏, "setName", "(Landroid/yunosjava/lang/String;)V");
jstring name = env->NewS数组公式tringUTF("David")数组的界说;
env->CallVo函数调用句子funcidMethod(person, methodID_setName,javascript name);
}

榜首过程用了Java层的办法来检测年岁是否源码年代合法,怎样合法就设置年岁。Java层的代码如下java游戏

    public boolean setAgeFromJni(int age) {
if (age < 0 || age > 200) {
t源码怎样做成app软件hrow new IllegalArgumentException("Age m源码编辑器ust be in [0, 200]");
}
mPerson.setAge(age);
return true;
}

虽然这个Java办法回来了一个b函数调用关系图oolean值,可是一旦抛出异常,是无法经过这个回来值检测异常的,因而只能在n数组的界说ative办法经过检测这个异常来判别Java层办法是否实行成功。

而假定Java层抛数组出了异常,而native层函数没有处理这个失数组词三声常,那么程序会挂掉。方才的代码中,只是简略经过 ExceptionClear() 铲除异常android11,并直接回来。当然还能够android是什么手机牌子有其它处理方案,例如从头设置一个合法的年岁,可是条件仍是要先铲除这个异常。

在native函数中检测到异常后,只需少数几个函数能够调用,其间函数调用句子func包括检测异常函数,可是请记住,不管你怎样处源码年代理异常,首要调用 Exce函数调用的三种办法ptionClear() 把这个异常给铲除android平板电脑多少钱了,之后再调用其它函数。

抛出异常

JNI 层能够处理自己的异常,例如操作数组产生的异常,也能处理Java层抛出的异常,例如调用Java办法而抛出的异常。其实JNI也能抛出一个Java异常让Java函数调用的三种办法办法处理。

抛出Javjava游戏a异常的函数如下

// 下面两个函数,数组正常状况下回来0,不然回来负值
jint Throw(JNIEnv *env, jthrowable obj);
ji数组指针nt ThrowNew(JNIEnv *env, jclass clazz, const char *message);

这两个函数都能够抛出异常,可是比较之后能够发javascript现,第二个函数更便利,因而榜首个函数要结android什么意思构一个Java异常政策,这个过程源码怎样做成app软件杂乱。

例如在Java层调用一个native办法,代码如下

extern "C"
JNIEXPORT void JNICALL
Java_com_example_helllojni_MainActi数组词三声vity_checkAge(JNIEnv *env, jobject thiz, jint age) {
if (age < 0 || age > 100) {
j源码资本c源码超市lass ex_clazz = env-java怎样读>FindClass("java/lang/IllegalArgumentException");
env->ThrowNew(ex_clazz, "Age rang函数调用句子funce [0, 100]!!!");
}
}

这个native办法数组词,检测年岁值假定不合法函数调用能够,抛出了一个 IllegalArg函数调用能够umentException。而在Java层,调用这个办法时,必需求处理这个异常的,不然程序披挂,代码如下

        try {
checkAAndroidge(-1);
} catch (Ex源码怎样做成app软件ception e) {
Log.d("david", "catch ex = " + e.getMessage());
}

工作感受

异常检测与处理,在JNI开发中是十分重要的一环,java环境变量配置咱们千万不行忽视,否函数调用过程则咱们很难找出JNI层的Bug在哪里。Andjava面试题roiandroid是什么手机牌子d的JNI源码中,有许多异常处理的代码,函数调用句子源码编辑器分值得咱们在阅读时进行学习。

参看

docs.oracle.com/jaandroid的drawable类vase/java开发工程师7/do…

docs.oracle.com/javase/7/do…