上層java代碼進行異常捕獲
try{
exception();
}catch (Exception e){
Log.e(TAG,e.getMessage());
}
//當出現異常的時候,下句代碼照樣可以執行
Log.e(TAG,"-------------------------------------------------");
jni 異常交給java層處理
NIEXPORT void JNICALL Java_com_example_jnitest_MainActivity_exception
(JNIEnv *env, jobject jobj){
jclass cls = (*env)->GetObjectClass(env,jobj);
//生成屬性簽名: 在class目錄下(build\intermediates\classes\debug\com\example\jnitest),
//執行javap -s 類名
//獲取某個類的屬性的時候注意:屬性簽名後面要有分號;
jfieldID fieldId = (*env)->GetFieldID(env,cls,"key","Ljava/lang/String;");
//檢查是否發生java異常,如果發生異常,只能在jni中捕獲
jthrowable throwable1 = (*env)->ExceptionOccurred(env);
//如果throwable 不等於null 說明發生異常
if(throwable1 != NULL){
//讓Java代碼可以繼續運行
//清空異常信息
(*env)->ExceptionClear(env);
//補救措施
fieldId = (*env)->GetFieldID(env,cls,"key","Ljava/lang/String;");
}
jstring str = (*env)->GetObjectField(env,jobj,fieldId);
//把jstring 轉成 c 中的String char*
const char* string = (*env)->GetStringUTFChars(env,str,NULL);
//判斷是否相等,如果不想等,則拋出異常
if(strcmp(string,"JJL2") != 0) {
jclass cls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
//向java層拋出異常,java層進行捕獲
(*env)->ThrowNew(env, cls, "key is invalid!!!");
}
}
jni 緩存處理
局部變量用static修飾之後,另外的方法也不能使用,當方法調用完成之後,其在內存中還存在,除非程序調用結束之後纔會釋放
JNIEXPORT void JNICALL Java_com_example_jnitest_MainActivity_cached
(JNIEnv *env, jobject jobj){
static jfieldID key_id = NULL;
if(key_id == NULL){
jclass cls = (*env)->GetObjectClass(env,jobj);
key_id = (*env)->GetFieldID(env,cls,"key","Ljava/lang/String;");
printf("--------GetFieldID-------\n");
//jni打印日誌,需要導入頭文件 #include <android/log.h>,
//然後在 Android.mk 文件中添加 LOCAL_LDLIBS += -llog
__android_log_print(ANDROID_LOG_INFO,"lgj ","--------GetFieldID-------");
}
}
//初始化全局變量,動態庫加載完成之後,立刻緩存起來
jfieldID key_fid;
JNIEXPORT void JNICALL Java_com_example_jnitest_MainActivity_initIds
(JNIEnv *env, jclass cls){
key_fid = (*env)->GetFieldID(env,cls,"key","Ljava/lang/String;");
__android_log_print(ANDROID_LOG_INFO,"lgj ","--------init-------");
}