JNI 异常捕获与处理

JNI 异常捕获与处理

jNI 异常捕获与处理,常见的 3 种情况:

  • native 层代码出错,native自己消费错误消息
  • java 层代码出错,导致 native 层调用出错
  • native 层代码没问题,调用 java 层代码出错

情况一:

native 层代码出错,native自己消费错误消息

native 层代码:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_jni_activity_ExceptionActivity_nativeException1(JNIEnv *env, jobject thiz) {

    jclass j_class = env->GetObjectClass(thiz);

    //这行代码会报错!!!
    jfieldID j_id = env->GetFieldID(j_class, "name", "Ljava/lang/String;");
    //TODO 方式一
    //判断是否发生过异常
    jthrowable j_thr = env->ExceptionOccurred();
    if (j_thr) {
        LOGE("检测到异常");
        //清除异常
        env->ExceptionClear();
    }
}

辅助图:
在这里插入图片描述
假设现在 name 属性没有找到,name 就会报错,在这里使用:

env->ExceptionOccurred();

可以检测到 JNI 代码是否报错
如果报错,那么清除掉错误:

 env->ExceptionClear();

情况二

java 层代码出错,导致 native 层调用出错

native 层代码:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_jni_activity_ExceptionActivity_nativeException2(JNIEnv *env, jobject thiz) {
    jclass j_class = env->GetObjectClass(thiz);
    //这行代码会报错!!!
    jfieldID j_id = env->GetFieldID(j_class, "name", "Ljava/lang/String;");

    //TODO 方式一
    //判断是否发生过异常
    jthrowable j_thr = env->ExceptionOccurred();
    //非 0 级 true
    if (j_thr) {
        LOGE("检测到异常");
        //清除异常
        env->ExceptionClear();

        //参数填写的是异常包名路径
        jclass null_class = env->FindClass("java/lang/NullPointerException");

        env->ThrowNew(null_class, "报错啦报错啦 NullPointerException!!");
    }
}

辅助图:
在这里插入图片描述
在调用 java 层代码的时候,发现 java 层代码会抛出一个 null 指针异常,那么在 JNI 层也要做相应的处理

和情况一 类似,先判断是否有过异常,如果有异常然后在清除异常,然后把异常信息返回给 java 层

//参数填写的是异常包名路径
jclass null_class = env->FindClass("java/lang/NullPointerException");

env->ThrowNew(null_class, "报错啦报错啦 NullPointerException!!");

findClass()解释:

  • 参数一:填写的是错误信息的路径:

运行结果为:
在这里插入图片描述

情况三

native 层代码没问题,调用 java 层代码出错

native层代码:

//TODO 方式三
extern "C"
JNIEXPORT void JNICALL
Java_com_example_jni_activity_ExceptionActivity_nativeException3(JNIEnv *env, jobject thiz) {
    jclass j_class = env->GetObjectClass(thiz);

    jmethodID j_id = env->GetStaticMethodID(j_class, "showExpetcion", "()V");
    //调用 java 层的异常方法 ,走到这里会崩溃
    env->CallStaticVoidMethod(j_class, j_id);

    //检查是否会崩溃(可以理解为 判断 java 层是否抛出异常)
    if (env->ExceptionCheck()) {
        //输出描述错误信息
        env->ExceptionDescribe();
        //清除掉崩溃信息
        env->ExceptionClear();
    }
}

辅助图:

在这里插入图片描述
可以屏蔽掉 java 层报错异常的信息

完整代码

其他 JNI 文章:

第一篇:Android JNI 入门(含完整Demo)

第二篇:Android JNI 进阶(含完整 Demo)

第三篇:Android JNI QQ 搞怪语音实战 (含完整 Demo)

第四篇:Andoird JNI动态注册与 JNI 线程

原创不易,您的点赞就是对我最大的支持~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

s10g

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值