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

异常处理

  • 1.保证Java代码可以运行
  • 2.补救措施保证C代码继续运行

//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!");
    }
}
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");
    }

}

缓存策略

//缓存策略
//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");
}
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();
    }

}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/android-ndk-basic-jni-exception-handling-jni-cache-policy/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Android NDK基础13:JNI异常处理_JNI缓存策略
异常处理 1.保证Java代码可以运行 2.补救措施保证C代码继续运行 //JNI自己抛出的异常,在Java层可以被捕捉(需注意是Exception、Throwable或者Error),也……
<<上一篇
下一篇>>
文章目录
关闭
目 录