Android JNI中如何使用try-catch捕获NewStringUTF抛出的异常?
结论
你当前的实现无法正常捕获NewStringUTF抛出的错误,原因如下:
JNI函数抛出的是Java虚拟机层面的异常,不属于C标准异常体系,即便开启了-fexceptions编译选项也无法通过std::exception捕获。具体来说NewStringUTF在内存不足时会抛出Java层面的OutOfMemoryError,只会将JVM标记为异常挂起状态,不会触发C异常抛出逻辑,你写的捕获分支永远不会执行。
正确实现方案
JNI异常统一通过JNI提供的接口检测处理,步骤如下:
- 调用
NewStringUTF后,调用env->ExceptionCheck()检测是否存在待处理的JNI异常 - 如果检测到异常,先调用
env->ExceptionClear()清空异常,避免异常传递到Java层导致崩溃 - 最后生成兜底的空字符串返回即可
正确代码示例:
jstring result; result = env->NewStringUTF(data.c_str()); // 检测JNI异常 if (env->ExceptionCheck()) { // 清空已抛出的异常 env->ExceptionClear(); // 返回兜底空字符串 result = env->NewStringUTF(""); } return result;
额外注意事项
- 所有JNI接口调用产生的异常都需要通过
ExceptionCheck/ExceptionOccurred检测,不要依赖C++异常捕获逻辑 - 检测到异常后如果需要继续调用JNI接口,必须先调用
ExceptionClear清空未处理的异常,否则后续JNI调用会直接崩溃 - 如果需要获取异常的具体信息,可以调用
env->ExceptionOccurred()拿到jthrowable对象,再通过JNI反射接口解析异常的类型和堆栈信息
内容的提问来源于stack exchange,提问作者Firas Chebbah
相关产品推荐
相关产品推荐

