现在我们知道了怎样使用native code访问简单的数据类型和引用参考类型(string,array),下面我们来介绍怎样让jni代码去访问java中的成员变量和成员函数,然后可以再jni中回调java中的方法。

-------------------------------------------------------------------------------------

Accessing fields

java提供2中成员,静态成员和非静态成员,JNI支持了怎么样去get和set这些静态以及非静态成员的方法,下面来举一个例子。

先来访问非静态成员。

我们先在类中声明一个非静态的成员变量:

[java] view plain copy
  1. publicclassMyJNIextendsActivity{
  2. /**Calledwhentheactivityisfirstcreated.*/
  3. //declearainstancefield
  4. privateStrings="123";


在点击按钮的时候我们把title的textview的字符串改成s,

[java] view plain copy
  1. MyJNImj=newMyJNI();
  2. mj.accessField();
  3. tv.setText(mj.s);


java代码很简单,只要实现我们的功能就好了,下面来看jni是如何进入class中的成员变量的:

[cpp] view plain copy
  1. Java_com_android_jni_MyJNI_accessField(JNIEnv*env,jobjectobj)
  2. {
  3. jfieldIDfid;
  4. jstringjstr;
  5. constchar*str;
  6. //getareferencetoobj'sclass
  7. jclasscls=(*env)->GetObjectClass(env,obj);
  8. //jclasscls=(*env)->FindClass(env,"com/android/jni/Native");
  9. __android_log_print(ANDROID_LOG_INFO,"-JNI-","hereinnativeC!");
  10. //lookfortheinstancefieldincls
  11. fid=(*env)->GetFieldID(env,cls,"s",
  12. "Ljava/lang/String;");
  13. if(fid==NULL){
  14. __android_log_print(ANDROID_LOG_INFO,"-JNI-","cannotfindfield");
  15. return;
  16. }
  17. //readtheinstancefields
  18. jstr=(*env)->GetObjectField(env,obj,fid);
  19. str=(*env)->GetStringUTFChars(env,jstr,NULL);
  20. if(str==NULL)
  21. return;
  22. (*env)->ReleaseStringUTFChars(env,jstr,str);
  23. //createanewstringandoverwritetheinstancefield
  24. jstr=(*env)->NewStringUTF(env,"abc");
  25. if(jstr==NULL)
  26. return;//outofmemory
  27. (*env)->SetObjectField(env,obj,fid,jstr);
  28. }


为了访问目标类中的成员变量,要做2步,首先呼叫GetFieldID从类中来得到一个field ID,根据成员的名字和描述:

fid = (*env)->GetFieldID(env,cls,"s",
"Ljava/lang/String;");

然后根据这个field ID来访问这个成员:

jstr = (*env)->GetObjectField(env,obj,fid);

因为在java中string是对象,所以这边呼叫的是GetObjectField函数。

最后运行模拟器,点击按钮的时候textView会变成JNI中修改的“abc”



ok,这部分结束,下面来看如何访问静态成员变量。

同样的java代码中:

[java] view plain copy
  1. publicclassMyJNIextendsActivity{
  2. /**Calledwhentheactivityisfirstcreated.*/
  3. //declearainstancefield
  4. privatestaticintsi=100;
  5. privateStrings="123";


我们定义一个静态的整形变量si初始化为100,当我们点击按钮的时候通过jni访问static field来改变si的值,然后再title的textView中显示出来。

[java] view plain copy
  1. MyJNImj=newMyJNI();
  2. mj.accessStaticField();
  3. tv.setText(mj.si+"");


我们来看下如何进入static field:

[cpp] view plain copy
  1. void
  2. Java_com_android_jni_MyJNI_accessStaticField(JNIEnv*env,jobjectobj)
  3. {
  4. jfieldIDfid;//storethefieldid
  5. jintsi;
  6. //getareferencetoobj'sclass
  7. jclasscls=(*env)->GetObjectClass(env,obj);
  8. __android_log_print(ANDROID_LOG_INFO,"-JNI-","hereinnativeC!");
  9. //lookforthestaticfieldsiinlcs
  10. fid=(*env)->GetStaticFieldID(env,cls,"si","I");
  11. if(fid==NULL)
  12. return;//fieldnotfound
  13. //accessthestaticfieldsi
  14. si=(*env)->GetStaticIntField(env,cls,fid);
  15. (*env)->SetStaticIntField(env,cls,fid,200);
  16. }


大家可以看到只是调用的方法不一样,多了一个static,和非静态的使用方法一样。

-------------------------------------------------------------------------------------------------------

jni中访问class 中的field就到此结束,下面一篇会介绍如何访问java中class 的method。

更多相关文章

  1. 序列化的两种方式
  2. 避免内存泄露专题
  3. Android配置环境变量
  4. Android(安卓)混淆 (不定期完善第三方混淆规则)
  5. Android(安卓)SDK 环境变量配置-Windows7-20170427
  6. Android开发(一):环境搭建
  7. Android中使用注解替代枚举
  8. Android里遇到Debug能用,Release不能用的API的问题
  9. android NDK 之C调java属性及方法

随机推荐

  1. Android 官方架构组件之 Lifecycle的学习
  2. Android Tcp服务器端
  3. android 实现微信摇一摇效果
  4. android Media process
  5. Android(安卓)SQLiteOpenHelper源码解读
  6. Android SQLite Database and ContentPro
  7. Android 关闭后台音频播放
  8. Android GPS获取当前位置信息
  9. Android下拉刷新实例
  10. android之listView缓存机制