Andriod JNI编程之C++回调Java函数
来源:互联网 发布:以公司名义开淘宝店 编辑:程序博客网 时间:2024/05/17 08:42
一般我们NDK编程都是Java层调用C++的接口,但其实才C++层也可以调用Java的函数。实现方法如下:
1、获取类名:jclass cls = env->FindClass
2、获取类方法:jmethodID mid = env->GetMethodID
3、获取类成员变量:fieldID fid=env->GetFieldID
4、生成类对象:jobject obj=env->NewObject (jobect也可以从Java层传下来)
5、调用类成员方法:env->CallXXXMethod(XXX为Java方法的返回值类型)
下面是一个例子:
首先是Java的代码,首先生成一个JniTest类,里面有个sayHelloFromJava的方法,我们要实现的目标是在C++里面赋值(String str),两个整形值(int index1, int index2),一个整形数组(int[] intArray),然后在Java里面将这些数值打印出来。
- public class JniTest extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- JNI j = new JNI();
- j.write();
- }
- public JniTest()
- {
- Log.i("TEST","JniTest Constructor");
- }
- public int sayHelloFromJava(String str, int index1, int index2, int[] intArray)
- {
- Log.i("TEST", str + " But I am show in java");
- Log.i("TEST", "index1 = " + index1 + " index2 = " + index2 );
- int javaIndex = 5;
- for(int i = 0; i < intArray.length; ++i)
- {
- Log.i("TEST", "intArray[i] = " + intArray[i]);
- }
- return javaIndex;
- }
- }
- public class JNI {
- static
- {
- System.loadLibrary("myjni");
- }
- public native void write();
- }
然后是C++里面的代码
- JNIEXPORT void JNICALL Java_cc_androidos_jni_JNI_write
- (JNIEnv *env, jobject j) {
- LOGI("calltest");
- jstring str = NULL;
- jclass clz = env->FindClass("cc/androidos/jni/JniTest");
- //获取clz的构造函数并生成一个对象
- jmethodID ctor = env->GetMethodID(clz, "<init>", "()V");
- jobject obj = env->NewObject(clz, ctor);
- // 如果是数组类型,则在类型前加[,如整形数组int[] intArray,则对应类型为[I,整形数组String[] strArray对应为[Ljava/lang/String;
- jmethodID mid = env->GetMethodID(clz, "sayHelloFromJava", "(Ljava/lang/String;II[I)I");
- if (mid)
- {
- LOGI("mid is get");
- jstring str1 = env->NewStringUTF("I am Native");
- jint index1 = 10;
- jint index2 = 12;
- //env->CallVoidMethod(obj, mid, str1, index1, index2);
- // 数组类型转换 testIntArray能不能不申请内存空间
- jintArray testIntArray = env->NewIntArray(10);
- jint *test = new jint[10];
- for(int i = 0; i < 10; ++i)
- {
- *(test+i) = i + 100;
- }
- env->SetIntArrayRegion(testIntArray, 0, 10, test);
- jint javaIndex = env->CallIntMethod(obj, mid, str1, index1, index2, testIntArray);
- LOGI("javaIndex = %d", javaIndex);
- delete[] test;
- test = NULL;
- }
- }
通过这个例子我们基本上就可以了解C++层是如何回调Java函数的了。另外,这里还有一个小技巧,如果你不知道你Java层的在C++中的类型是什么,你可以native方法中将这个类型写进去,然后用javah方法生成.h文件,只要查看.h文件的对应的类型注释就可以知道结果了。例如:我们想知道String、整形数组对应的类型怎么写,我们在native中加入一个public native void type(String str, int[] arrayInt)方法
- public class JNI {
- static
- {
- System.loadLibrary("myjni");
- }
- public native void write();
- public native void type(String str, int[] arrayInt);
- }
然后生成对应的.h文件:
- /*
- * Class: cc_androidos_jni_JNI
- * Method: type
- * Signature: (Ljava/lang/String;[I)V
- */
- JNIEXPORT void JNICALL Java_cc_androidos_jni_JNI_type
- (JNIEnv *, jobject, jstring, jintArray);
我们注意看注释中的“Signature: (Ljava/lang/String;[I)V”,其中Ljava/lang/String;Ljava/lang/String;就是String的类型(注意分号不能丢),[I则是整形数组对应的类型。
- Andriod JNI编程之C++回调Java函数
- Andriod JNI编程之C++回调Java函数
- Andriod JNI编程之C++回调Java函数
- Andriod JNI编程之C++回调Java函数
- Andriod JNI编程之C++回调Java函数
- JNI编程:C++回调Java函数
- Ndk学习之JNI构造函数(java-->C-->Java)
- JNI之 c/c++调用java构造函数
- JNI使用实例之C、C++ DLL回调java成员函数
- Java之JNI编程注意事项
- JNI编程中C调用Java实现。
- java c语言混合编程 jni
- JNI之C语言(四)-- 函数
- Android JNI编程(八)——体验AS2.2.2编写Jni程序、Java调C、C调Java函数、将C代码中的Log打印至Logcat
- andriod网络编程--C实现
- Java通过JNI调用C/C++函数
- C/C++调用java---JNI常用函数
- JAVA通过JNI调用C函数Demo
- Objective C--建造者模式
- make menuconfig 时,出现错误:unable to find the ncurses libraries
- Java多线程编程--(7)学习Java5.0 并发编程包--Lock & Condition
- win8应用开发之一:创建一个使用 C#/VB 和 XAML 的 Metro 风格应用
- 【科普】中华民族复兴任务算法...不是网传的10月1到10月1
- Andriod JNI编程之C++回调Java函数
- ICON下载,Win8,Metro风格
- 一步一步学习Spring(3)-管理Bean之间的关系二(自动依赖检查)
- Eclipse在Ubuntu下无法双击启动解决办法
- Caused by: java.io.UTFDataFormatException: Invalid byte 3 of 3-byte UTF-8 sequence
- OMA-DM概述
- window常用命令大全
- 通向架构师的道路(第六天)之漫谈基于数据库的权限系统的设计(转载)
- 日记2012-8-8