Android - JNI - 通过JNI恢复MyException成员

时间:2011-08-10 22:59:43

标签: android java-native-interface

在我的Java代码中,我使用getCustomCode()方法创建了MyException类(扩展了Exception类)。

在我的C ++代码中,当我调用抛出MyException的Java方法时,我需要执行此异常的getCustomCode以正确处理异常。

为了实现这一点,我使用以下代码执行抛出MyException的Java方法:

jint result = env->CallIntMethodA(javaObj, methodId, params);

在此行之后,我使用以下代码检查JavaException:

jthrowable exc = env->ExceptionOccurred();
if(exc)
{
    jclass objCls = env->FindClass("com/mycompany/myapp/exception/MyException");
    jmethodID codeMethod = env->GetMethodID(objCls, "getCustomCode", "()I");
    if(!objCls || !codeMethod){ ........ }
    // Try to execute getCustomCode java method.
    jint codeResult = env->CallIntMethod((jobject)exc, codeMethod);
    ...
    ...
}

但是,当我尝试通过JNI执行getCustomCode时,它失败了。 我用JNI方法IsAssignableFrom和IsInstanceOf做了一些检查,结果是:

jclass objCls = env->FindClass ("com/mycompany/myapp/exception/MyException");
jclass objThrowable = env->FindClass ("java/lang/Throwable");
if(env->IsAssignableFrom(objCls, objThrowable) == JNI_TRUE) { /* TRUE! */ }

条件返回true,所以我的班级是正确的。 另一项检查:

jclass objCls = env->FindClass ("com/mycompany/myapp/exception/MyException");
jclass objThrowable = env->FindClass ("java/lang/Throwable");
if(env->IsInstanceOf((jobject)exc, objCls) == JNI_TRUE) { /* FALSE */ }
if(env->IsInstanceOf((jobject)exc, objThrowable) == JNI_TRUE) { /* FALSE */ }

两个条件都返回false,因此MyException和Throwable都不是exc类!

那么,jthrowable对象是什么?如何将jthrowable对象转换为jobject以访问MyException成员? 可能吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

您很可能需要在env->ExceptionClear()等之前调用env->FindClass(...)。在异常处于活动状态时,不允许调用大多数JNI方法,请参阅this page的第6.2.2节。存在待处理异常时允许的函数列表:

ExceptionOccurred
ExceptionDescribe
ExceptionClear
ExceptionCheck
ReleaseStringChars
ReleaseStringUTFchars
ReleaseStringCritical
Release<Type>ArrayElements
ReleasePrimitiveArrayCritical
DeleteLocalRef
DeleteGlobalRef
DeleteWeakGlobalRef
MonitorExit