jni 異常交給java層進行捕獲及jni緩存策略

上層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-------");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章