概述
在 Java 里有两种类型的域: 实例域和静态域 。Java类的每个实例都有自己的实例存储空间。而一个类的所有实例共享一个静态域。那么在 JNI NDK 开发中如何去访问呢? JNI中是提供了访问两种类型域的方法的。
JNI NDK访问 实例域和静态域
在Android使用JNI提供的方法访问域之前,我们需要创建一个Java类,这个类包含实例域和静态域。
一、创建带有实例域和静态域的Java类
创建一个ApiCenter类,包含instanceField和staticField的成员变量( 如图:有实例域和静态域的ApiCenter类.png )
有实例域和静态域的ApiCenter类.png
二、想要获取到对应的域,我们需要获取对应域的域ID
1.先要获取到类。 使用 GetObjectClass 方法获取到类 (如图: 获取到类.png )
获取到类.png
2. 获取 实例域 的 ID使用GetFieldId方法(如图:获取实例域ID.png),根据获取到的类jclass,获取对应的域ID。
获取实例域ID.png
2. 获取 静态域 的 ID使用GetStaticFieldId方法(如图:获取静态域ID .png )
获取静态域ID.png
三、获取域的方法
在第二步中我们拿到对应的域ID以后,可以用GetTypeField函数来获取实际的域。JNI NDK中提供了对应类型的获取域的方法(如图:获取域的全部方法.png)。其中的Type可以是: Boolean 、 Char 、 Short 、Int、 Long 、 Float 、 Double ,Object。
获取域的全部方法.png
四、 根据域ID去获取域
1.获取到实例域:使用GetObjectField(如图:获得实例域.png)
获得实例域.png
/** * "instanceField"是实例的名字。 * "LJava/lang/String;" 是实例的描述信息 */ instanceFieldId = _env->GetFieldID(jclazz, "instanceField", "LJava/lang/String;"); jstring instanceField; instanceField = (jstring) _env->GetObjectField(jObj, instanceFieldId);
2.获取到静态域: 使用GetStaticObjectField(如图:获得静态域.png)
获得静态域.png
staticFieldId = _env->GetStaticFieldID(jclazz, “staticField”, “LJava/lang/String;”);
jstring staticField;
staticField = (jstring) _env->GetStaticObjectField(jclazz, staticFieldId);
总结
通过上面的过程,我们想要获取到单个域的值需要使用三个JNI层的函数。Native代码回到Java中获取到每个单独的域值给程序增加了额外的负担。所以建议把需要的参数传递到Native层。
喜欢就关注我吧。
欢迎点赞。
欢迎有问题随时在评论区留言。有不同的见解也可以在评论区留言交流。谢谢。