在JNI中,有的情况,C中需要调用java的方法来实现某些功能。下面就来简单的解析,如何使用JNI调用java中的方法:
其中主要包括:调用java非静态方法,调用java的静态方法,调用java的构造方法这三大类
调用java的非静态方法:
首先,在java中定义非静态方法:
public int showToast(){
Toast.makeText(getApplicationContext(),"showToast",Toast.LENGTH_SHORT).show();
return 0;
}
上面,随便声明了一个java方法。
然后通过JNI调用这个方法:
JNIEXPORT void JNICALL
Java_com_example_administrator_dnndkfilesplit_MainActivity_acessMethod(JNIEnv *env,jobject instance) {
//首先获取jclass
jclass jclz=env->GetObjectClass(instance);
//获取待访问的方法id
jmethodID mid=env->GetMethodID(jclz,"showToast","()I"); //这个方法是无参方法,如果需要带参数 ,方法签名和下面的调用有些区别
//访问java中的方法
env->CallIntMethod(instance,mid);
}
首先通过jObject对象获取jclass,拿到jclass之后再获取方法ID,其中需要传入方法id,方法id的获取方式可以通过javap命令,也可以直接写,有一定的规律。注意:在c和c++中书写有些区别。以上代码都是在c++
调用静态方法:
public static String getRandomUUID(){
return UUID.randomUUID().toString();
}
上面定义一个静态方法,通过java API获取UUID,这个在c语言中,就比较难实现。JNI就可以调用java中的方法来获取UUID,异曲同工。
JNIEXPORT void JNICALL
Java_com_example_administrator_dnndkfilesplit_MainActivity_accessStaticMethod(JNIEnv *env,jobject instance) {
jclass jclz=env->GetObjectClass(instance);
jmethodID jmid=env->GetStaticMethodID(jclz,"getRandomUUID","()Ljava/lang/String;");
LOGD("jmid ");
//然后就是调用,获取uuid 一般uuid是数据库的id或者文件的名字
jstring uuid= (jstring) env->CallStaticObjectMethod(jclz, jmid);
//将jstring 转换成char *
char * uuid_c= (char *) env->GetStringUTFChars(uuid, 0);
LOGD("uuid is %s",uuid_c);
}
跟调用非静态方法的区别是:这里获取方法ID方式和调用的时候有细小的差别。这里,还进行了输出。
访问构造方法:
构造方法,这里就不再特别的声明一个构造方法了,这里打算调用java类库中的/java/util/Date.java 这个类的无参构造方法,并调用getTime这个方法,获取时间。
JNIEXPORT jobject JNICALL
Java_com_lpf_ndk_MainActivity_accessLocalConstructor(JNIEnv *env,jobject instance) {
jclass jclz=env->FindClass("java/util/Date");
LOGD("jclz");
//然后就是方法ID 构造方法,统一使用名称"<init>"
jmethodID jmid=env->GetMethodID(jclz,"<init>","()V");
jobject date_obj=env->NewObject(jclz,jmid); //通过初始化构造方法,来获取类对象
LOGD("date_obj");
//获取getTime() 方法的签名
jmethodID jmid_time=env->GetMethodID(jclz,"getTime","()J");
LOGD("jmid_time");
jlong time=env->CallLongMethod(date_obj,jmid_time);
LOGD("time");
return date_obj;
}
总结:
通过JNI调用java的方法,都是需要,首先获取jclass,然后根据拿到的jclass去获取方法id,然后根据方法id调用相应的方法。