爲了從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;
}