Android NDK开发教程:对类变量进行操作详解
程序员文章站
2023-12-10 16:59:46
通常我们也可以直接利用jni来访问和处理类的变量,不一定非要通过java方法来操作java类变量。对类变量操作时,类的静态变量和类的实例变量的操作稍微有些不同,下面进行讲解。
对类的静态变量进行操作...
通常我们也可以直接利用jni来访问和处理类的变量,不一定非要通过java方法来操作java类变量。对类变量操作时,类的静态变量和类的实例变量的操作稍微有些不同,下面进行讲解。
对类的静态变量进行操作
类的静态变量属于类,是所有该类实例共享的。操作该变量时,不需要指定具体的实例是哪个。
jclass clazz; jfieldid fid; jint num; //1.获取类的class引用 clazz = env->findclass("zqc/com/example/person"); if (clazz == 0) { // 错误处理 return; } //2.获取类静态变量num的属性id fid = env->getstaticfieldid( clazz, "num", "i"); if (fid == 0) { return; } // 3.获取静态变量num的值 num = env->getstaticintfield(clazz,fid); printf("in c--->classfield.num = %d\n", num); // 4.修改静态变量num的值 env->setstaticintfield(clazz, fid, 80);
主要步骤就是代码里面注释的。
对类的实例变量进行操作
代码如下:
jclass clazz; jfieldid fid; jstring j_str; jstring j_newstr; const char *c_str = null; // 1.获取类的class引用,obj是该类的某个实例jobject obj; clazz = env->getobjectclass(obj); if (clazz == null) { return; } // 2. 获取类实例变量str的属性id fid = env->getfieldid(clazz,"str", "ljava/lang/string;"); if (clazz == null) { return; } // 3. 获取实例变量str的值 j_str = (jstring)env->getobjectfield(obj,fid); // 4. 将unicode编码的java字符串转换成c风格字符串 c_str = env->getstringutfchars(j_str,null); if (c_str == null) { return; } printf("in c--->classfield.str = %s\n", c_str); env->releasestringutfchars(j_str, c_str); // 5. 修改实例变量str的值 j_newstr = env->newstringutf("this is c string"); if (j_newstr == null) { return; } env->setobjectfield(obj, fid, j_newstr); // 6.删除局部引用 env->deletelocalref(clazz); env->deletelocalref(j_str); env->deletelocalref(j_newstr);
jni开发也有jni开发的套路,按照上面套路来,即可修改类的实例变量。操作过程也很好理解,我们在native操作的时候都需要借助jni提供的函数获取相应的引用。利用引用去进行操作。由于jni函数是直接操作jvm中的数据结构,所以即使是private的变量,我们也可以进行修改。
总结
由于jni函数是直接操作jvm中的数据结构,不受java访问修饰符的限制。即,在本地代码中可以调用jni函数可以访问java对象中的非public属性和方法
访问和修改静态变量操作步聚:
调用findclass函数获取类的class引用
调用getstaticfieldid函数获取class引用中某个静态变量id
调用getstaticxxxfield函数获取静态变量的值,需要传入变量所属class的引用和变量id
调用setstaticxxxfield函数设置静态变量的值,需要传入变量所属class的引用、变量id和变量的值
访问和修改实例变量操作步聚:
调用getobjectclass函数获取实例对象的class引用
调用getfieldid函数获取class引用中某个实例变量的id
调用getxxxfield函数获取变量的值,需要传入实例变量所属对象和变量id
调用setxxxfield函数修改变量的值,需要传入实例变量所属对象、变量id和变量的值