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