Android NDK基础13:JNI异常处理_JNI缓存策略

异常处理

  • 1.保证Java代码可以运行
  • 2.补救措施保证C代码继续运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//JNI自己抛出的异常,在Java层可以被捕捉(需注意是Exception、Throwable或者Error),也可在C层清空
//用户通过ThrowNew抛出的异常,可以在Java层捕捉
JNIEXPORT void JNICALL Java_cn_appblog_jni_JniTest_exeception(JNIEnv *env, jobject jobj) {
jclass cls = (*env)->GetObjectClass(env, jobj);
jfieldID fid = (*env)->GetFieldID(env, cls, "key2", "Ljava/lang/String;");
//检测是否发生Java异常
jthrowable exception = (*env)->ExceptionOccurred(env);
if (exception != NULL) {
//让Java代码可以继续运行
//清空异常信息
(*env)->ExceptionClear(env);

//补救措施
fid = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");
}

//获取属性的值
jstring jstr = (*env)->GetObjectField(env, jobj, fid);
char *str = (*env)->GetStringUTFChars(env, jstr, NULL);

//对比属性值是否合法
if (_stricmp(str, "super yezhou") != 0) {
//人为抛出异常,给Java层处理
jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
(*env)->ThrowNew(env, newExcCls, "key's value is invalid!");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class JniTest {

public String key = "yezhou";

public native void exeception();

public static void main(String[] args) {
JniTest t = new JniTest();

try {
t.exeception();
} catch (Exception e) {
//} catch (Throwable e) {
//} catch (Error e) {
System.out.println("发生异常:" + e.getMessage());
}

System.out.println("--------异常发生之后-------");
}

//加载动态库
static {
System.loadLibrary("JniTest");
}

}

缓存策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//缓存策略
//static jfieldID key_id
JNIEXPORT void JNICALL Java_cn_appblog_jni_JniTest_cached(JNIEnv *env, jobject jobj) {
jclass cls = (*env)->GetObjectClass(env, jobj);
//获取jfieldID只获取一次
//局部静态变量
static jfieldID key_id = NULL; //只赋值一次,生命周期与应用程序一致
//jfieldID key_id = NULL; //赋值多次
if (key_id == NULL) {
key_id = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");
printf("--------GetFieldID-------\n");
}
}

//初始化全局变量,动态库加载完成之后,立刻缓存起来
jfieldID key_fid;
jmethodID random_mid;
JNIEXPORT void JNICALL Java_cn_appblog_jni_JniTest_initIds(JNIEnv *env, jclass jcls) {
key_fid = (*env)->GetFieldID(env, jcls, "key", "Ljava/lang/String;");
random_mid = (*env)->GetMethodID(env, jcls, "genRandomInt", "(I)I");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class JniTest {

public String key = "yezhou";

public native void cached();

public native static void initIds();

public static void main(String[] args) {
JniTest t = new JniTest();

//不断调用cached方法
for (int i = 0; i < 100; i++) {
t.cached();
}
}

//加载动态库
static {
System.loadLibrary("JniTest");
initIds();
}

}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :