zoukankan      html  css  js  c++  java
  • NDK学习笔记-JNI的异常处理与缓存策略

    在使用JNI的时候,可能会产生异常,此时就需要对异常进行处理

    异常处理

    JNI抛出Throwable异常,在Java层可以用Throwable捕捉
    而在C只有清空异常这种处理
    但如果在JNI中通过ThrowNew抛出异常,则在Java曾可以捕获
    例子(在native访问不存在的属性)
    Java中声明native方法

    public native void exception();
    

    在native中进行处理

    JNIEXPORT void JNICALL Java_com_cj5785_jni_JniTest_exception
    (JNIEnv *env, jobject jobj)
    {
    	jclass cls = (*env)->GetObjectClass(env, jobj);
    	jfieldID fid = (*env)->GetFieldID(env, cls, "key0", "Ljava/lang/String;");
    	//检测是否发生Java异常
    	jthrowable exception = (*env)->ExceptionOccurred(env);
    	if (exception != NULL)
    	{
    		//清空异常信息
    		(*env)->ExceptionClear(env);
    		//抛出异常给Java层
    		jclass exception_cls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
    		(*env)->ThrowNew(env, exception_cls, "key0 is not invalid");
    	}
    }
    

    此处访问了一个不存在的属性,通过ThrowNew将异常抛给Java处理
    有时候需要在native中添加补救措施,这取决于实际的运用场景

    因此在异常处理的时候,要保证Java能够正常运行

    缓存策略

    在多次获取同一个属性或对象的时候,使用缓存,可以有效减少属性和对象的内存占用

    在使用的时候定义

    定义一个static变量,保证其生成的只有一个,这样就节省了内存
    局部static的生命周期随着程序而存在,作用于在其定义的代码块内

    JNIEXPORT void JNICALL Java_com_cj5785_jni_JniTest_cached
    (JNIEnv *env, jobject jobj)
    {
    	jclass cls = (*env)->GetObjectClass(env, jobj);
    	//设置局部静态变量,保证其只会被赋值一次
    	static jfieldID key_id = NULL;
    	if (key_id == NULL)
    	{
    		key_id = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");
    	}
    }
    

    初始化时候定义

    初始化全局变量,动态库加载完成之后,立刻存储起来
    那么在调用的时候就需要在加载完成立即调用

    static {
    		System.loadLibrary("JNITest");
    		initIds();
    }
    
    public native static void initIds();
    

    在native中定义全局,然后对其进行赋值

    jfieldID key_fid;
    jmethodID random_mid;
    JNIEXPORT void JNICALL Java_com_cj5785_jni_JniTest_initIds
    (JNIEnv *env, jclass jcls)
    {
    	key_fid = (*env)->GetFieldID(env, jcls, "key", "Ljava/lang/String;");
    	random_mid = (*env)->GetMethodID(env, jcls, "getRandomInt", "(I)I");
    }
    
  • 相关阅读:
    html 上传图片前预览
    php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
    php 计算 pdf文件页数
    php 获取半年内每个月的订单数量, 总价, 月份
    php 获取两个数组之间不同的值
    小程序支付功能
    关于nginx的Job for nginx.service failed because the control process exited with error code.错误
    linux 安装 Apollo
    MongoDB待续。。。
    ABP vNext...待续
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664677.html
Copyright © 2011-2022 走看看