JNI异常处理

来源:互联网 发布:马士兵java教程百度云 编辑:程序博客网 时间:2024/05/22 17:05

《Pro Android C++ with the NDK》学习笔记

  • 捕获异常
  • 抛出异常
  • JNI异常处理

在JNI中发生的异常和Java完全不一样。我们在写JNI程序的时候,JNI没有像Java一样有try…catch…final这样的异常处理机制,并且在本地代码中调用某个JNI接口时如果发生了异常,后续的本地代码不会立即停止执行,而会继续往下执行后面的代码。

一、捕获异常

JNIEnv接口提供了一组与异常相关的函数集,在运行过程中可以使用Java类查看这些函数。

public class JavaClass{// 抛出方法private void throwingMethod() throws NullPointerException{throw new NullPointerException("Null Pointer");}/*** Access methods native method.*/private native void accessMethods();}

调用throwingMethod方法时,accessMethod原生方法需要显示地做异常处理。JNI提供了ExceptionOccurred函数查询虚拟机中是否有挂起的现象。例如,原生代码中的异常处理:

jthrowable ex;……(*env)->CallVoidMethod(env,instance,throwingMethodId);ex = (*env)->ExceptionOccurred(env);if(0 != ex){// 清除引发的异常(*env)->ExceptionClear(env);/*Exception handler*/}

二、抛出异常

JNI也允许原生代码抛出异常。因为异常是java类,应该先用FindClass函数找到异常类。用ThrowNew函数可以初始化且抛出新的异常,例如:

jclass clazz;……clazz = (*env)->FindClass(env,"java/lang/NullPointerException");if(0 !=clazz){(*env)->ThrowNew(env,clazz,"Exception message");}

当检测到异常时,我们可以调用ExceptionDescribe函数打印这个异常的堆栈信息,然后再调用ExceptionClear函数清除异常堆栈信息的缓冲区(如果不清除,后面调用ThrowNew抛出的异常堆栈信息会覆盖前面的异常信息),最后调用ThrowNew函数手动抛出一个java.lang.Exception异常。

但在JNI中抛出未捕获的异常与Java的异常处理机制不一样,在JNI中并不会立即终止本地方法的执行,而是继续执行后面的代码。这种情况需要我们手动来处理,在执行完异常处理之后直接return返回,不再执行之后的代码。