[JNI]开发之旅(7)JNI函数中调用java对象的方法
2016-12-31 20:51
323 查看
在jni函数中我们不仅要对java对象的数据域进行访问,而且有时也需要调用java中类对象已经实现的方法。接下来我们对对象的方法调用,调用步骤与访问数据域相似。
定义一个setSex方法,通过accessPublicMethod在jni实现给java对象的变量sex赋值
JNI层代码
这里有几个地方注意GetMethodID获取methodID需要传入jclass,CallVoidMethod需要传入对象实例jobject,前面文章以及介绍过原因,这里不在多说;Ljava/lang/String不要写成Ljava.lang.String否则会找不到方法。
运行结果:
调用private方法就不用实例实现了,只需要把setSex方法改成private,其他代码实现与public没有区别。在c/c++层,java的访问域无效。
jni实现:
运行结果:
定义一个SuperUtils让前面定义的JNIUtils继承于它,然后在SuperUtils中定义一个hello方法,通过jni实现调用java父类方法
JNI代码实现:
这里与前面有几个不同点:
1.通过反射FindClass获取到父类的class,而不是JNIUtils的class
2.调用CallNonvirtual【Type】Method方法来实现调用父类方法
Nonvirtual:继承而来的非虚拟函
这节简单的介绍了jni函数怎么调用java对象的方法及父类的方法,要熟悉可以多动手按照上面介绍的步骤,去实现其他类型返回值/参数类型的方法,加深印象。下一节将介绍对java对象构造器的访问。
源码下载:https://github.com/honjane/JNIDemo
1.获得实例对应的class类 2.根据class类获得方法的method id 3.根据method id和对象实例获取方法 4.操作方法
实例1:JNI方法java对象public方法
java代码定义一个setSex方法,通过accessPublicMethod在jni实现给java对象的变量sex赋值
private String sex = "female";//需要赋初始值或定义成static,不然在没有调用accessPublicMethod方法前,调用getSex方法会抛异常 public void setSex(String sex){ this.sex = sex; } public String getSex(){ return sex; } public native void accessPublicMethod();
JNI层代码
//访问java中public方法 extern "C" void Java_com_honjane_ndkdemo_JNIUtils_accessPublicMethod( JNIEnv* env, jobject jobj){ //1.获得实例对应的class类 jclass jcls = env->GetObjectClass(jobj); //2.通过class类找到对应的method id //name 为java类中变量名,Ljava/lang/String; 为变量的类型String jmethodID jmid = env->GetMethodID(jcls,"setSex","(Ljava/lang/String;)V"); //定义一个性别赋值给java中的方法 char c[10] = "male"; jstring jsex = env->NewStringUTF(c); //3.通过obj获得对应的method env->CallVoidMethod(jobj,jmid,jsex); }
这里有几个地方注意GetMethodID获取methodID需要传入jclass,CallVoidMethod需要传入对象实例jobject,前面文章以及介绍过原因,这里不在多说;Ljava/lang/String不要写成Ljava.lang.String否则会找不到方法。
运行结果:
I/main----sex赋值前: female I/main----sex赋值后: male
调用private方法就不用实例实现了,只需要把setSex方法改成private,其他代码实现与public没有区别。在c/c++层,java的访问域无效。
实例2:JNI方法java对象static方法
java层代码:定义一个static的getHeight()方法,通过accessStaticMethod在jni函数中实现调用。private static int height = 160; public static int getHeight(){ return height; } public native int accessStaticMethod();
jni实现:
//访问java中static方法 extern "C" jint Java_com_honjane_ndkdemo_JNIUtils_accessStaticMethod( JNIEnv* env, jobject jobj){ //1.获得实例对应的class类 jclass jcls = env->GetObjectClass(jobj); //2.通过class类找到对应的method id jmethodID jmid = env->GetStaticMethodID(jcls,"getHeight","()I"); //3.静态方法通过class获得对应的method return env->CallStaticIntMethod(jcls,jmid); }
运行结果:
I/main----height调用JNI方法: 160
实例3:JNI函数访问java类的父类方法
java层代码:定义一个SuperUtils让前面定义的JNIUtils继承于它,然后在SuperUtils中定义一个hello方法,通过jni实现调用java父类方法
public class SuperUtils { public String hello(String msg){ return "2017 " + msg; } } ..... public class JNIUtils extends SuperUtils{ public native String accessSuperMethod(); ...... }
JNI代码实现:
//访问java中父类方法 extern "C" jstring Java_com_honjane_ndkdemo_JNIUtils_accessSuperMethod( JNIEnv* env, jobject jobj){ //1.通过反射获得父类的class类 jclass jpcls = env->FindClass("com/honjane/ndkdemo/SuperUtils"); if(jpcls == NULL){ char c[10] = "error"; return env->NewStringUTF(c); } //2.通过class类找到对应的method id jmethodID jmid = env->GetMethodID(jpcls,"hello","(Ljava/lang/String;)Ljava/lang/String;"); char c[20] = "happy new year"; jstring new_str = env->NewStringUTF(c); //3.静态方法通过class获得对应的method return (jstring)env->CallNonvirtualObjectMethod(jobj,jpcls,jmid,new_str); }
这里与前面有几个不同点:
1.通过反射FindClass获取到父类的class,而不是JNIUtils的class
2.调用CallNonvirtual【Type】Method方法来实现调用父类方法
Nonvirtual:继承而来的非虚拟函
这节简单的介绍了jni函数怎么调用java对象的方法及父类的方法,要熟悉可以多动手按照上面介绍的步骤,去实现其他类型返回值/参数类型的方法,加深印象。下一节将介绍对java对象构造器的访问。
源码下载:https://github.com/honjane/JNIDemo
相关文章推荐
- Android NDK开发之Jni调用Java对象
- Android NDK开发之Jni调用Java对象
- Android NDK开发之JNI调用Java对象
- Android-本地方法与Java相互调用-自定义ProgressBar(锅炉压力监测例子)/NDK-JNI开发实例(七)
- 【学习Android NDK开发】native code通过JNI调用Java方法
- Android JNI开发之c语言调用java方法
- 转:Android NDK开发之Jni调用Java对象
- 【学习Android NDK开发】native code通过JNI调用Java方法
- #菜鸟之旅#Android Studio开发JNI工程——Native调用Java方法获取IMEI
- 【学习Android NDK开发】native code通过JNI调用Java方法
- Android NDK开发之JNI调用Java对象
- 【JNI开发】C++调用java函数的实现方法
- [JNI]开发之旅(6)JNI函数中访问java类中对象的属性
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android NDK开发之Jni调用Java对象
- JNI学习之---用jni API 访问java对象的属性,方法,调用构造器。
- 安卓应用开发通过java调用c++ jni的图文使用方法
- 【学习Android NDK开发】native code通过JNI调用Java方法
- 【学习Android NDK开发】native code通过JNI调用Java方法
- Android NDK开发之Jni调用Java对象