为了从JNI中抛出一个java异常,首先,使用FindClass()找到对应的类(像使用java的反射API);这里通过JNI提供的机制,很好的介绍了java的回调。在JNI中使用指定的jcalss来表示引用的java类。这里使用jclass类型来描述一个异常实例,并在当前类加载器中通过完整名称(包含包路径)来搜索类描述符。此外,我们不长时间需要引用异常类时,可以使用DeleteLocalRef()来解除引用。
注意:不要忘记处理返回值;
FindClass()和JNI方法可能会失败的原因如下:没有足够的可用内存、类没有找到等等
一旦异常抛出,就不会调用JNI异常清理方法(DeleteLocalRef()、DeleteGlobalRef()等等)。本地代码将清理它的资源并将控制交给后面的java,如果没有java被调用,它可能执行本地处理(native process)。当被地方法返回时,异常被VM传递给JAVA。
如果其他地方不需要再使用时,需要删除本地引用(指向类描述符)。当JNI借给你东西时,不要忘记还回去。
1、实现一个java异常类(InvalidTypeException.java)
public class InvalidTypeException extends Exception {
public InvalidTypeException(String pDetailMessage){
super(pDetailMessage);
}
}
2、在java的JNI接口类中指定抛出异常()
public class Store {
static {
System.loadLibrary("store");
}
public native int getInteger(String pKey)
throws NotExistingKeyException, InvalidTypeException; //指定抛出两个异常
}
3、在java中处理抛出的异常信息
try{
if(sItem == "Integer") {
mUIValueEdit.setText( Integer.toString(mStore.getInteger(lKey)) );
}
else if (sItem == "String"){
mUIValueEdit.setText( mStore.getString(lKey) );
}
}
catch(NotExistingKeyException eNotExistingKeyException){
displayError("Key does not exist in Store");
}
catch(InvalidTypeException eInvalidTypeException){
displayError("错误的数据类型");
}
Java中的异常处理已经完成,现在我们可以在JNI中来抛出上面定义的异常。
4、JNI中实现一个异常抛出方法
void throwInvalidTypeException(JNIEnv* pEnv)
{
jclass lClass = (*pEnv)->FindClass(pEnv,“com/packtpub/exception/InvalidTypeException”);
if (lClass != NULL) {
(*pEnv)->ThrowNew(pEnv, lClass, “Invalid Type.”);
}
//如果我们长时间不再需要引用这个异常类时,可以使用DeleteLocalRef()来解除它。
(*pEnv)->DeleteLocalRef(pEnv, lClass);
}
5、JNI中调用4中的方法,抛出异常
int32_t isEntryValid(JNIEnv* pEnv, StoreEntry* pEntry, StoreType pType)
{
if (pEntry->mType != pType) {
throwInvalidTypeException(pEnv); //抛出异常
}
else {
return 1;
}
return 0;
}