0
点赞
收藏
分享

微信扫一扫

Android JNI 内存管理

泠之屋 2022-01-20 阅读 82

①数据类型:Java与JNI数据对应关系      

Javanative描述Javanative描述
基本数据类型引用数据类型
booleanjbooleanunsigned 8位Stringjstirng字符串对象
bytejbytesigned 8位ClassjclassClass类
charjcharunsigned 16位Objectjobject任何对象
shortjshortsigned 16位Object[]jobjectArray

任何对象数组

intjintsigned 32位boolean[]jbooleanArray布尔数组
longjlongsigned 64位int[]jintArrayint数组
floatjfloat32位浮点char[]jcharArraychar数组
doublejdouble64位浮点byte[]jbyteArraybyte数组
short[]jshortArrayshort数组
long[]jlongArraylong数组
floatjfloatArrayfloat数组
doublejdoubleArraydouble数组
特殊类型voidvoid

②方法签名:

Java数据类型对应JNI中的方法参数描述符
常见数据类型在JNI中的描述符,常见于JNI调用Java方法的时候
intI(大写i)
booleanZ(注意不是B)
floatF
byteB
doubleD
charC
longJ
shortS
String

Ljava/lang/String;

ObjectLjava/lang/Object;
ClassLjava/lang/Class;
char[][C
Object[][Ljava/lang/Object;
ArrayListLjava/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;
// }
}

 

举报

相关推荐

0 条评论