在Android NDK C ++代码中捕获异常

时间:2016-10-17 21:49:34

标签: android c++ android-ndk java-native-interface

我试图在Android上捕获本机C ++代码中的错误。根据docs,当类名无法找到时,FindClass返回NULL。但我得到FATAL EXCEPTION: main java.lang.NoClassDefFoundError: fake/class并且执行从未到达if语句。

#include <string.h>
#include <jni.h>

extern "C"
void Java_com_example_MainActivity_testError(JNIEnv *env, jobject) {
    jclass clazz = env->FindClass("fake/class");
    // never gets here
    if (clazz == NULL) {
        return;
    }
}

此异常也会跳过try-catch块并导致应用程序崩溃。我的Java代码:

static {
    System.loadLibrary("native-lib");
}

public native void testError();

...
try {
    testError();
} catch (Exception e) {
    // exception never get cought
}

我也使用cppFlags '-fexceptions'。是否有正确的方法来捕获此异常或从中恢复,以便应用程序不会崩溃?

1 个答案:

答案 0 :(得分:1)

首先,为防止本机代码在FindClass等上崩溃,您必须在每次JNI调用后使用此代码:

bool checkExc(JNIEnv *env) {
    if (env->ExceptionCheck()) {
        env->ExceptionDescribe(); // writes to logcat
        env->ExceptionClear();
        return true;
    }
    return false;
}

实际上,ExceptionClear()会停止崩溃。我在这个答案https://stackoverflow.com/a/33777516/2424777

上找到了代码

其次,为了确保从本机代码中捕获所有崩溃,您必须使用此try-catch。 Credits @Richard Critten也可以在所有本机函数调用中使用它:

static {
    try {
        System.loadLibrary("native-lib");
    } catch (Error | Exception ignore) { }
}

cppFlags&#39; -fexceptions&#39;无所事事,所以你可以删除它。