zoukankan      html  css  js  c++  java
  • NDK开发之访问域

    Java有两类域,实例域和静态域。类的每个实例都有自己的实例域副本,而一个类的所有实例共享一个静态域(Java SE基础)。

    JNI提供了相应的函数来访问这两类域,总体步骤是这样的:


    1.通过对象引用获得类
    2.通过类获得域ID
    3.通过域ID获取域


    下面我们按步骤一步一步来:
    我们的Java类中有两个域,一个静态域,一个实例域:

        private static String staticFiled = "a static Filed465";
        private String instanceFiled = "a instance Filed123";

    访问该域的三个步骤:

    1通过对象引用获得类

    jclass clazz;
        //定义域ID
        jfieldID instanceFieldId;
        jfieldID staticFieldId;
        //定义域
        jstring instanceFieldStr;
        jstring staticFieldStr;
        //通过对象引用获得类
        clazz = (*env)->GetObjectClass(env, thiz);

    2通过类获得域ID

    //通过类获得域ID
        instanceFieldId = (*env)->GetFieldID(env,clazz,"instanceFiled","Ljava/lang/String;");
        staticFieldId = (*env)->GetStaticFieldID(env,clazz,"staticFiled","Ljava/lang/String;");

    这里两个函数的最后一个参数是Java中表示域类型的域描述符,"Ljava/lang/String;"表明域类型是String。
    一般情况下,为了提高应用程序的性能,我们可以缓存域ID,一般总是缓存使用最频繁的域ID

    3.通过域ID获取域

        //通过域ID获得域
        instanceFieldStr = (*env)->GetObjectField(env,thiz,instanceFieldId);
        staticFieldStr = (*env)->GetStaticObjectField(env,clazz,staticFieldId);

    为了证明我们已经成功获得域,我们把jstring转为c字符串之后然后打印出来(打印日志请看NDK开发之日志打印):

        const jbyte* str1;
        const jbyte* str2;
        str1 = (*env)->GetStringUTFChars(env,instanceFieldStr,0);
        str2 = (*env)->GetStringUTFChars(env,staticFieldStr,0);
        LOGI("the string is :%s",str1);
        LOGI("the string is :%s",str2);

    打印结果:

    这里写图片描述


    完整的程序是这样的:


    void Java_com_example_jni_MainActivity_updateField(JNIEnv* env, jobject thiz) {
        jclass clazz;
        //定义域ID
        jfieldID instanceFieldId;
        jfieldID staticFieldId;
        //定义域
        jstring instanceFieldStr;
        jstring staticFieldStr;
        //通过对象引用获得类
        clazz = (*env)->GetObjectClass(env, thiz);
        //通过类获得域ID
        instanceFieldId = (*env)->GetFieldID(env,clazz,"instanceFiled","Ljava/lang/String;");
        staticFieldId = (*env)->GetStaticFieldID(env,clazz,"staticFiled","Ljava/lang/String;");
        //通过域ID获得域
        instanceFieldStr = (*env)->GetObjectField(env,thiz,instanceFieldId);
        staticFieldStr = (*env)->GetStaticObjectField(env,clazz,staticFieldId);
        //jstring转为C字符串然后打印出来
        const jbyte* str1;
        const jbyte* str2;
        str1 = (*env)->GetStringUTFChars(env,instanceFieldStr,0);
        str2 = (*env)->GetStringUTFChars(env,staticFieldStr,0);
        LOGI("the string is :%s",str1);
        LOGI("the string is :%s",str2);
    }

    总结

    大家都看到了,获得单个域需要三个步骤,这真是太麻烦了,经常这样搞会影响程序的性能,因此建议如果在原生方法中需要 使用域,这些域最好作为参数传递给原生方法,而不要让原生代码回到Java中。


    版权声明:本文为博主原创文章,未经博主允许不得转载。若有错误地方,还望批评指正,不胜感激。

  • 相关阅读:
    c3p0用c3p0-config.xml方式配置 和 用spring配置时一点小区别
    mysql配置
    tomcat监控工具Probe
    tomcat配置
    jsp页面动态包含和静态包含
    servlet3的文件上传
    System.currentTimeMillis()和new Date().getTime()比较
    js-html2canvas导出html图片 导出pdf
    html中使用富文本编辑器
    Vue----vue-resource
  • 原文地址:https://www.cnblogs.com/lenve/p/4889324.html
Copyright © 2011-2022 走看看