文章目录
I . 设置 Java 对象 属性 流程
II . 查找 Java 对象属性 ( GetFieldID )
III . 设置 Java 对象属性 ( SetXxxField )
I . 设置 Java 对象 属性 流程
设置 Java 对象字段流程 :
① 获取属性 ID :
调用 jfieldID GetFieldID(jclass clazz, const char* name, const char* sig) 方法 , 获取对象属性 ID ;
② 根据属性 ID 设置对象属性 :
调用 void SetIntField(jobject obj, jfieldID fieldID, jint value) 方法 , 设置对象属性 ;
II . 查找 Java 对象属性 ( GetFieldID )
1 . 函数原型 : 通过 jclass 对象 , 属性名称名称 , 和 类型签名 , 获取 Java 类对象对应的 属性 ID ;
返回值 : Java 类对象 对应的 属性 ID ( jfieldID 类型变量 )
参数 :
jclass clazz : 要获取的 Java 对象方法对应的 Java 类对象 ; const char* name : 属性名称 ; const char* sig : 类型签名 ; struct _JNIEnv { /* _JNIEnv 结构体中封装了 JNINativeInterface 结构体指针 */ const struct JNINativeInterface* functions; ... // 最终 调用的 还是 JNINativeInterface 结构体中封装的 GetFieldID 方法 jfieldID GetFieldID(jclass clazz, const char* name, const char* sig) { return functions->GetFieldID(this, clazz, name, sig); } ... }
2 . 代码示例 : 获取 Student 类的 getAge 方法 ;
student_class 是 Student 类对应的 C/C++ 中的 jclass 类型变量 ; “age” 是 属性名称 ; “I” 是 属性类型签名 ; extern "C" JNIEXPORT void JNICALL Java_kim_hsl_jni_MainActivity_jniObjectTest(JNIEnv *env, jobject instance, jobject student) { ... //1 . 获取 Java 对应的 Class 对象 jclass student_class = env->GetObjectClass(student); //2 . 获取 Student 的 private int age 属性 jfieldID age_field_id = env->GetFieldID(student_class, "age", "I"); ... }
涉及到的类型签名可以参考 : https://hanshuliang.blog.csdn.net/article/details/104108556#V__javap_____141
III . 设置 Java 对象属性 ( SetXxxField )
1 . 函数原型 : 通过 Java 对象 , 属性 ID , 和 Java 数据类型属性参数 , 设置对应的 Java 对象属性 ;
返回值 : void
参数 :
jobject obj : 要设置属性的 Java 对象 ; jfieldID fieldID : 属性 ID ; jint value : Java 的 int 类型属性值 ; struct _JNIEnv { /* _JNIEnv 结构体中封装了 JNINativeInterface 结构体指针 */ const struct JNINativeInterface* functions; ... // 最终 调用的 还是 JNINativeInterface 结构体中封装的 SetIntField 方法 void SetIntField(jobject obj, jfieldID fieldID, jint value) { functions->SetIntField(this, obj, fieldID, value); } ... }
2 . 设置方法汇总 :
设置 int 类型属性 , 调用 void SetIntField(jobject obj, jfieldID fieldID, jint value) 方法 ;
设置 boolean 类型属性 , 调用 void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) 方法 ;
下面是设置 8 种基本数据类型 和 引用类型 , 共 9 中类型应该调用的方法 ;
注意 : 所有设置的类型 , 都是 Java 数据类型 , 如 jobject , jint , jboolean 类型 ;
struct _JNIEnv { /* _JNIEnv 结构体中封装了 JNINativeInterface 结构体指针 */ const struct JNINativeInterface* functions; ... // 最终 调用的 还是 JNINativeInterface 结构体中封装的 SetXxxField 方法 void SetObjectField(jobject obj, jfieldID fieldID, jobject value) { functions->SetObjectField(this, obj, fieldID, value); } void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) { functions->SetBooleanField(this, obj, fieldID, value); } void SetByteField(jobject obj, jfieldID fieldID, jbyte value) { functions->SetByteField(this, obj, fieldID, value); } void SetCharField(jobject obj, jfieldID fieldID, jchar value) { functions->SetCharField(this, obj, fieldID, value); } void SetShortField(jobject obj, jfieldID fieldID, jshort value) { functions->SetShortField(this, obj, fieldID, value); } void SetIntField(jobject obj, jfieldID fieldID, jint value) { functions->SetIntField(this, obj, fieldID, value); } void SetLongField(jobject obj, jfieldID fieldID, jlong value) { functions->SetLongField(this, obj, fieldID, value); } void SetFloatField(jobject obj, jfieldID fieldID, jfloat value) { functions->SetFloatField(this, obj, fieldID, value); } void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value) { functions->SetDoubleField(this, obj, fieldID, value); } //设置静态属性 jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig) { return functions->GetStaticMethodID(this, clazz, name, sig); } ... }
3 . 代码示例 : 获取 Student 类的 getAge 方法 ;
student 是 Student 类对应的 C/C++ 中的 Java 对象 ; age_field_id 是 属性 ID ; 90 是 属性值 , jint 类型 ; extern "C" JNIEXPORT void JNICALL Java_kim_hsl_jni_MainActivity_jniObjectTest(JNIEnv *env, jobject instance, jobject student) { ... //1 . 获取 Java 对应的 Class 对象 jclass student_class = env->GetObjectClass(student); //2 . 获取 Student 的 private int age 属性 jfieldID age_field_id = env->GetFieldID(student_class, "age", "I"); //3 . 设置 Student 的 age 属性值 90 env->SetIntField(student, age_field_id, 90); ... }