JNI 异常捕获与处理
Posted null.....
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 QQ 搞怪语音实战 (含完整 Demo)
原创不易,您的点赞就是对我最大的支持~
以上是关于JNI 异常捕获与处理的主要内容,如果未能解决你的问题,请参考以下文章
Android NDK开发篇:Java与原生代码通信(异常处理)