VII . 反射获取类静态方法 ( GetStaticMethodID )
函数原型 : 通过 jclass 对象 , 方法名称 , 和 方法签名 , 获取 Java 类对象对应的方法 ID 即 jmethodID 类型变量 ;
返回值 : Java 类对象对应的方法 ID ( jmethodID 类型变量 )
参数 :
jclass clazz : 要获取的 Java 对象方法对应的 Java 类对象 ; const char* name : 方法名称 ; const char* sig : 方法签名 , 使用 javap 命令获得 ; struct _JNIEnv { /* _JNIEnv 结构体中封装了 JNINativeInterface 结构体指针 */ const struct JNINativeInterface* functions; ... // 最终 调用的 还是 JNINativeInterface 结构体中封装的 GetStaticMethodID 方法 jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig) { return functions->GetStaticMethodID(this, clazz, name, sig); } ... }
2 . 代码示例 : 获取 Student 类的 getAge 方法 ;
student_class 是 Student 类对应的 C/C++ 中的 jclass 类型变量 , “logInfo” 是方法名称 , “(Ljava/lang/String;)V” 是方法签名 , 左侧的括号是参数列表类型签名 , 括号右的 V 是返回值类型 void ; 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 的 public static void logInfo(String info) 方法 // 注意这里要使用 GetStaticMethodID 方法反射该静态方法 jmethodID method_logInfo = env->GetStaticMethodID(student_class, "logInfo" , "(Ljava/lang/String;)V"); ... }
VIII . 调用 Java 对象方法 ( CallXxxMethod )
注意 : 返回值和参数必须 都是 Java 类型 ;
函数原型 : 通过 Java 对象 , Java 方法 ID , 及根据函数签名传入的 参数列表 ( 可变参数 ) , 反射调用该 Java 对象的方法 ;
返回值 : Void , 注意这里的返回值可以是 8 种 基本数据类型 , jboolean , jbyte , jshort 等类型 , 也可以是引用类型 jobject 类型 , 只有这 10 种返回类型 , 没有其它类型 ; ( 注意 : 返回值 都是 Java 类型 )
参数 :
jobject obj : 要获取的 Java 对象方法对应的 Java 类对象 ; jmethodID methodID : 方法 ID ; … : 可变参数 , 方法的参数 ( 注意 : 参数 必须 都是 Java 类型 ) ; struct _JNIEnv { /* _JNIEnv 结构体中封装了 JNINativeInterface 结构体指针 */ const struct JNINativeInterface* functions; ... // 最终 调用的 还是 JNINativeInterface 结构体中封装的 CallVoidMethod 方法 void CallVoidMethod(jobject obj, jmethodID methodID, ...) { va_list args; va_start(args, methodID); functions->CallVoidMethodV(this, obj, methodID, args); va_end(args); } ... }
2 . 所有 Java 方法调用返回值类型 :
jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...); jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list); jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...); jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list); jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list); jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...); jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list); jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list); jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...); jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list); jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...); jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list); jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...); jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list); jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
3 . 代码示例 : 调用 Student 类的 getAge 方法 ;
student 是 Student 类对象 , “method_getAge” 是方法 ID 由于没有参数 , 因此后面的可变参数列表为空 ; 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 的 public static void logInfo(String info) 方法 // 注意这里要使用 GetStaticMethodID 方法反射该静态方法 jmethodID method_logInfo = env->GetStaticMethodID(student_class, "logInfo" , "(Ljava/lang/String;)V"); //3 . 调用 Student 的 public int getAge() 方法 jint age = env->CallIntMethod(student, method_getAge); ... }
IX . 调用 Java 类静态方法 ( CallStaticXxxMethod )
注意 : 返回值和参数必须 都是 Java 类型 ;
函数原型 : 通过 Java 类对象 ( Class 对象 对应 C/C++ jclass 类型对象 ) , Java 方法 ID , 及根据函数签名传入的 参数列表 ( 可变参数 ) , 反射调用该 Java 对象的方法 ;
返回值 : Void , 注意这里的返回值可以是 8 种 基本数据类型 , jboolean , jbyte , jshort 等类型 , 也可以是引用类型 jobject 类型 , 只有这 10 种返回类型 , 没有其它类型 ; ( 注意 : 返回值 都是 Java 类型 )
参数 :
jobject obj : 要获取的 Java 对象方法对应的 Java 类对象 ; jmethodID methodID : 方法 ID ; … : 可变参数 , 方法的参数 ( 注意 : 参数 必须 都是 Java 类型 ) ; struct _JNIEnv { /* _JNIEnv 结构体中封装了 JNINativeInterface 结构体指针 */ const struct JNINativeInterface* functions; ... // 最终 调用的 还是 JNINativeInterface 结构体中封装的 CallStaticVoidMethodV 方法 void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...) { va_list args; va_start(args, methodID); functions->CallStaticVoidMethodV(this, clazz, methodID, args); va_end(args); } ... }
2 . 所有 Java 方法调用返回值类型 :
jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...); jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list); jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...); jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, va_list); jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...); jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list); jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...); jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list); jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...); jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list); jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...); jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list); jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...); jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list); jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...); jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list); jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...); jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list); jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list); void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);