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

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

我正在 try catch Android 上 native C++ 代码中的错误。根据文档,当找不到类名时,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 block 并使应用程序崩溃。我的Java代码:

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

public native void testError();

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

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

最佳答案

首先,为了防止 native 代码在 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

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

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

并且 cppFlags '-fexceptions' 与此无关,因此您可以将其删除。

关于android - 在 Android NDK C++ 代码中捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40096235/

相关文章:

c++ - 不允许在类定义之外覆盖

c++ - 如何将两个字符串从 Swift 传递到 C++ 函数,并获取整数数组?

Android - 缺少 NDK 平台?

android - "exist"附近的 SQLite 故障

Android sqlite - 如何管理 where 子句中的整数值

android - Google Play 服务无法验证,操作 : SIGN_IN status: 10

android - 从 Firebase 监听器发出状态 - Kotlin Flow

c++ 你能命名子窗口以使其句柄静态吗?

android - Cygdrive 终端错误 : opus/src/opus. o 失败

android - SIGBUS 仅在三星 Galaxy S2 上崩溃