上层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-------");
}