①数据类型:Java与JNI数据对应关系
Java | native | 描述 | Java | native | 描述 | |
---|---|---|---|---|---|---|
基本数据类型 | 引用数据类型 | |||||
boolean | jboolean | unsigned 8位 | String | jstirng | 字符串对象 | |
byte | jbyte | signed 8位 | Class | jclass | Class类 | |
char | jchar | unsigned 16位 | Object | jobject | 任何对象 | |
short | jshort | signed 16位 | Object[] | jobjectArray | 任何对象数组 | |
int | jint | signed 32位 | boolean[] | jbooleanArray | 布尔数组 | |
long | jlong | signed 64位 | int[] | jintArray | int数组 | |
float | jfloat | 32位浮点 | char[] | jcharArray | char数组 | |
double | jdouble | 64位浮点 | byte[] | jbyteArray | byte数组 | |
short[] | jshortArray | short数组 | ||||
long[] | jlongArray | long数组 | ||||
float | jfloatArray | float数组 | ||||
double | jdoubleArray | double数组 | ||||
特殊类型void | void |
②方法签名:
Java数据类型 | 对应JNI中的方法参数描述符 |
---|---|
常见数据类型在JNI中的描述符,常见于JNI调用Java方法的时候 | |
int | I(大写i) |
boolean | Z(注意不是B) |
float | F |
byte | B |
double | D |
char | C |
long | J |
short | S |
String | Ljava/lang/String; |
Object | Ljava/lang/Object; |
Class | Ljava/lang/Class; |
char[] | [C |
Object[] | [Ljava/lang/Object; |
ArrayList | Ljava/util/ArrayList; |
... | ... |
③代码举例:注:这里只是做了调用举例,没有考虑native内存回收。关于内存管理,详见 JNI内存管理 章节。Flash类见 JNI开发 章节
//方法签名举例子
extern "C"
JNIEXPORT void JNICALL
Java_com_helper_jnidemo_MainActivity_test(JNIEnv *env, jobject thiz) {
//获取Java类
jclass flash = env->FindClass("com/helper/jnidemo/Flash");
// 获取Java类 Flash 的无参构造方法,
// 类的构造方法名为比较特殊,为<init>;
// 方法签名为V,代表void,没有返回值;
// 且因为是无参构造函数,没有入参
jmethodID init = env->GetMethodID(flash, "<init>", "()V");
//构造Flash对象,用于后面代码讲解
jobject obj = env->NewObject(flash, init);
//对应Java层方法
// public Flash(){
//
// }
//获取Flash类的有参构造方法
//描述符解释:I对应int, C:char, F:float, D:double, Z:boolean, [C对应char[], Ljava/lang/String; 对应 String
//()里为构造函数方法入参,所以按照顺序添加描述符
jmethodID init1 = env->GetMethodID(flash, "<init>", "(ICFDZ[CLjava/lang/String;)V");
//对应Java层方法
// public Flash(int age, char firstName, float speed, double weight, boolean gender, char[] array,String name) {
// this.age = age;
// this.firstName = firstName;
// this.speed = speed;
// this. weight = weight;
// this.gender = gender;
// this.array = array;
// this.name = name;
// }
//获取类的age参数的get方法,参数类型为int,该方法名为getAge,返回值为int类型,且方法没有入参
jmethodID getAge = env->GetMethodID(flash, "getAge", "()I");
//调用getAge方法,返回值为int类型,
int age = env->CallIntMethod(obj, getAge);
//获取类的age参数的set方法,参数类型为int,该方法名为setAge,void方法,入参为int类型
jmethodID setAge = env->GetMethodID(flash, "setAge", "(I)V");
//调用setAge方法,其为void方法
env->CallVoidMethod(obj, setAge, 24);
//对应Java层方法
// public int getAge() {
// return age;
// }
//
// public void setAge(int age) {
// this.age = age;
// }
//获取类的name参数的get方法,参数类型为String,该方法名为getName,返回值为String类型,且没有入参
jmethodID getName = env->GetMethodID(flash, "getName", "()Ljava/lang/String;");
//调用getName方法,返回值为String类型,
// 注:方法返回值是非基本数据类型的,都是要用CallObjectMethod方法调用
jobject name = env->CallObjectMethod(obj, getName);
//获取name的set方法,方法名setName,无返回值,入参String
jmethodID setName = env->GetMethodID(flash, "setName", "(Ljava/lang/String;)V");
//调用setName方法,其为void方法,入参为Java String对象
//JNI 通过NewStringUTF创建String
env->CallVoidMethod(obj, setName, env->NewStringUTF("Flash"));
//对应Java层方法
// public String getName() {
// return name;
// }
//
// public void setName(String name) {
// this.name = name;
// }
//获取array参数的get方法,参数类型是char[],方法名 getArray,返回值char[],无入参
jmethodID getArray = env->GetMethodID(flash, "getArray", "()[C");
//调用getArray方法,返回值为char[]类型
// 注:方法返回值是非基本数据类型的,都是要用CallObjectMethod方法调用
jobject array = env->CallObjectMethod(obj, getArray);
//获取array参数的set方法,参数类型char[],方法名setArray,无返回值,入参char[]
jmethodID setArray = env->GetMethodID(flash, "setArray", "([C)V");
//调用setArray方法,其为void方法,入参为char[]
//JNI里面通过NewCharArray方法构造char[]
env->CallVoidMethod(obj, setArray, env->NewCharArray(3));
//对应Java层方法
// public char[] getArray() {
// return array;
// }
//
// public void setArray(char[] array) {
// this.array = array;
// }
}