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

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

Accessing fields

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

先来访问非静态成员。

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

[java]  view plain copy

 
  1. public class MyJNI extends Activity {
  2. /** Called when the activity is first created. */
  3. //declear a instance field
  4. private String s="123";

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

[java] 
view plain
copy

 

  1. MyJNI mj = new MyJNI();
  2. mj.accessField();
  3. tv.setText(mj.s);

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

[cpp] 
view plain
copy

 

  1. Java_com_android_jni_MyJNI_accessField(JNIEnv *env,jobject obj)
  2. {
  3. jfieldID fid;
  4. jstring jstr;
  5. const char *str;
  6. //get a reference to obj's class
  7. jclass cls = (*env)->GetObjectClass(env,obj);
  8. //  jclass cls = (*env)->FindClass(env,"com/android/jni/Native");
  9. __android_log_print(ANDROID_LOG_INFO,"-JNI-","here in native C!");
  10. //look for the instance field in cls
  11. fid = (*env)->GetFieldID(env,cls,"s",
  12. "Ljava/lang/String;");
  13. if(fid == NULL){
  14. __android_log_print(ANDROID_LOG_INFO,"-JNI-","can not find field");
  15. return;
  16. }
  17. //read the instance field s
  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. //create a new string and overwrite the instance field
  24. jstr = (*env)->NewStringUTF(env,"abc");
  25. if(jstr == NULL)
  26. return; //out of memory
  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. public class MyJNI extends Activity {
  2. /** Called when the activity is first created. */
  3. //declear a instance field
  4. private static int si=100;
  5. private String s="123";

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

[java] 
view plain
copy

 

  1. MyJNI mj = new MyJNI();
  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,jobject obj)
  3. {
  4. jfieldID fid;   //store the field id
  5. jint si;
  6. //get a reference to obj's class
  7. jclass cls = (*env)->GetObjectClass(env,obj);
  8. __android_log_print(ANDROID_LOG_INFO,"-JNI-","here in native C!");
  9. //look for the static field si in lcs
  10. fid = (*env)->GetStaticFieldID(env,cls,"si","I");
  11. if(fid == NULL)
  12. return; //field not found
  13. //access the static field si
  14. si = (*env)->GetStaticIntField(env,cls,fid);
  15. (*env)->SetStaticIntField(env,cls,fid,200);
  16. }

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

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

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

android jni ——Field & Method --> Accessing Field的更多相关文章

  1. android jni (5)——Field & Method --> Accessing Mehtod

    在java编程语言中有非静态成员函数和静态成员函数,JNI允许我们访问到java中的成员函数,然后再jni中调用,这里我就来举例说明在jni中是如何做到的. 我们先在java中定义2个成员函数,一个非 ...

  2. graphQL 启动报错No method or field found with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment] as the last argument), in priority order:

    -------------------root.graphqls---------------------------这个文件用来定义属性字段,必须和实体类相同 文件里面的字段写错会报这个错误 com ...

  3. Constructor、Method、Field 源码阅读

    AnnotatedElement /** * AnnotatedElement 接口表示目前正在此 VM 中运行的应用程序的一个已注解元素[类.方法.属性]. * 该接口允许反射性地读取注解.此接口中 ...

  4. NDK(5) Android JNI官方综合教程[JavaVM and JNIEnv,Threads ,jclass, jmethodID, and jfieldID,UTF-8 and UTF-16 Strings,Exceptions,Native Libraries等等]

    JNI Tips In this document JavaVM and JNIEnv Threads jclass, jmethodID, and jfieldID Local and Global ...

  5. Android jni系统变量、函数、接口定义汇总

    在做Android jni开发时,jni为我们提供了哪些函数.接口.变量,有时候一头雾水,今天就把jni.h中定义的所有内容列出来,供自己查阅: /* * Copyright (C) 2006 The ...

  6. 【转】android JNI

    原文网址:http://jinguo.iteye.com/blog/696185 Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码 ...

  7. Android JNI学习(四)——JNI的常用方法的中文API

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  8. Android JNI作用及其详解

    Android JNI作用及其详解 Java Native Interface (JNI)标准是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 J ...

  9. android JNI 资料大全

    AndroidJNI 通过C++调用JAVA 1. JNIEnv对象    对于本地函数    JNIEXPORT void JNICALL Java_video1_TestNative_sayHel ...

随机推荐

  1. swift2.0 UIImagePickerController 拍照 相册 录像

    系统 ios9.1 语言swift2.0 在app 里最常用的功能就是多媒体选择,首先我们storyboard 创建一个button 用于触发选择事件 @IBAction func selectIma ...

  2. getInitParameter()

      getInitParameter()方法是在GenericServlet接口中新定义的一个方法,用来调用初始化在web.xml中存放的参量.在web.xml配置文件中一个servlet中参量的初始 ...

  3. Dynamics CRM 2016 使用Plug-in Trace Log调试插件

    1.写插件 首先,让我们写一个简单的插件来测试新插件跟踪日志功能.请注意,在下面的示例代码中,我们增加ITracingService的一个实例,以及记录有关插件的执行信息记录的一些键值: 2.注册插件 ...

  4. JavaScript 公有 私有 静态属性和方法

    1.公有属性和公有方法 这里的 name  age  都是参数传递进去 可以在外面直接实例化调用. 2.私有属性和方法 私有的只能在函数内部使用 作用域的原因 3.静态属性和静态方法 这里我首先 创建 ...

  5. asp.net mvc 页面缓存

    在任务中需要实现点击浏览器back按钮,加载的前一页面需要强制刷新. 想要在前端通过js来绑定数据实现,但是觉得太麻烦,还是用另一种方式来解决: 不缓存该页面. 简单易懂: Response.Cach ...

  6. Oracle存储过程procedure

    --给plsql块设置一个名称保存下来便于调用 /* Create or replace procedure 名称 As 声明变量 Begin //代码块 End; --plsql块 Declare ...

  7. MySql函数应用

    -- 当前时间 now(); -- 查询结果串联(逗号) select group_concat(col_name) from table_name;

  8. arm汇编(c内嵌汇编及c和汇编互调)

    C语言编译成汇编: arm-linux-gcc -S test.c -o test.S C语言编译成可执行文件: arm-linux-gcc test.c -o test 多个文件编译链接: arm- ...

  9. [C入门 - 游戏编程系列] 贪吃蛇篇(二) - 食物定义

    游戏中的食物没有那么多复杂属性,特别是贪吃蛇游戏中,我把食物看待的很简单: 1. 它必须属于世界,才能出现在世界.不可能一个不属于世界的食物,出现在世界中:但是可能存在着一个食物,它属于世界,但是却没 ...

  10. 为什么1Byte=8bit

    Byte是字节的意思,而字节在早期计算机内部是用标准ASCII码来表示的根据当时情况确定至多有128种需要表示的字符(当时是IBM的标准,现在普遍是255),也就是2的7次方用二进制的0和1来表示就需 ...