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中。


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

时间: 2024-10-22 06:40:21

NDK开发之访问域的相关文章

NDK开发之调用方法

与NDK开发之访问域中介绍的一样,Java中的方法也是分为两类:实例方法和静态方法.JNI提供了访问两类方法的函数,下面我们一起来看看怎么在C中访问Java中的方法. 我们的MainActivity中有两个方法,分别是: private String instanceMethod(){ return "Instance Method"; } private static String staticMethod(){ return "static Method"; }

JNI/NDK开发指南(五)——访问数组(基本类型数组与对象数组)

转载请注明出处:http://blog.csdn.net/xyang81/article/details/42346165 JNI中的数组分为基本类型数组和对象数组,它们的处理方式是不一样的,基本类型数组中的所有元素都是JNI的基本数据类型,可以直接访问.而对象数组中的所有元素是一个类的实例或其它数组的引用,和字符串操作一样,不能直接访问Java传递给JNI层的数组,必须选择合适的JNI函数来访问和设置Java层的数组对象.阅读此文假设你已经了解了JNI与Java数据类型的映射关系,如果还不了解

Android NDK开发篇(五):Java与原生代码通信(数据操作)

尽管说使用NDK能够提高Android程序的运行效率,可是调用起来还是略微有点麻烦.NDK能够直接使用Java的原生数据类型,而引用类型,由于Java的引用类型的实如今NDK被屏蔽了,所以在NDK使用Java的引用类型则要做对应的处理. 一.对引用数据类型的操作 尽管Java的引用类型的实如今NDK被屏蔽了,JNI还是提供了一组API,通过JNIEnv接口指针提供原生方法改动和使用Java的引用类型. 1.字符串操作 JNI把Java的字符串当作引用来处理,在NDK中使用Java的字符串,须要相

Android NDK 开发(三)--常见错误锦集合Log的使用【转】

转载请注明出处:http://blog.csdn.net/allen315410/article/details/41826511  Android NDK开发经常因某些因素会出现一些意想不到的错误,很多时候调试这些错误的时候,显得比调试Java代码要复杂,一方面是导致错误的原因很多很杂,另一方面NDK开发涉及到C/C++代码的编写,很多程序员对此不熟悉.那么这篇博客就总结一下,在NDK开发中经常出现的一些问题,并且尝试提供一些正确的解决方案,方便在开发时能够快速定位到错误,更改错误,当然了,错

NDK开发基本知识

(3) NDK开发中乱码问题 解决乱码思路 : C语言编译的时候用的是 ISO-8859-1 码表进行编码, 如果我们使用C语言jni开发, 需要进行转码操作; -- 将ISO-8859-1转为UTF-8字符: String string = new String(str.getBytes("iso8859-1"), "UTF-8"); 示例 : 添加中文jni调用 : 将jni中的hello.c 中返回的字符串修改为中文, 重新编译 .so 静态库文件; -- 修

JNI/NDK开发指南(八)——调用构造方法和父类实例方法

转载请注明出处:http://blog.csdn.net/xyang81/article/details/44002089 在第6章我们学习到了在Native层如何调用Java静态方法和实例方法,其中调用实例方法的示例代码中也提到了调用构造函数来实始化一个对象,但没有详细介绍,一带而过了.还没有阅读过的同学请移步<JNI/NDK开发指南(六)--C/C++访问Java实例方法和静态方法>阅读.这章详细来介绍下初始一个对象的两种方式,以及如何调用子类对象重写的父类实例方法. 我们先回过一下,在J

ndk开发教程以及问题解决方案

一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言.但这并不等同于“第三方应用只能使用Java”.在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的. 不过,Google也表示,使

Android之NDK开发

一篇文章: Android之NDK开发 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言.但这并不等同于“第三方应用只能使用Java”.在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可

【转】Android之NDK开发

原文网址:http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言.但这并不等同于“第三方应用只能使用Java”.在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应