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 条评论