1、主要流程
1、新建一个测试类TestProvider.java
a)该类提供了2个方法
b)一个静态的方法,一个非静态的方法
2、JNI中新建Provider.c
a)该文件中需要把Java中的类TestProvider映射到C中
b)把TestProvider的两个方法映射到C中
c)新建TestProvider对象
d)调用两个方法
3、Android上层 调用JNI层
4、JNI层调用C层
5、C层调用Java方法
2、设计实现
1、界面设计如下:
老样子,很搓,不过实用,嘿嘿
代码不在这贴出了,有需要的兄弟直接到文章结束部分下载。
2、关键代码说明
C中定义映射的类、方法、对象
jclass TestProvider;
jobject mTestProvider;
jmethodID getTime;
jmethodID sayHello;
C中映射类
TestProvider = (*jniEnv)->FindClass(jniEnv,"com/duicky/TestProvider");
C中新建对象
jmethodID construction_id = (*jniEnv)->GetMethodID(jniEnv, TestProvider,"", "()V");
TestProvider mTestProvider = (*jniEnv)->NewObject(jniEnv, TestProvider,construction_id);
C中映射方法
静态:
getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestProvider, "getTime","()Ljava/lang/String;");
非静态:
sayHello = (*jniEnv)->GetMethodID(jniEnv, TestProvider, "sayHello","(Ljava/lang/String;)V");
C中调用Java的方法
静态:
(*jniEnv)->CallStaticObjectMethod(jniEnv, TestProvider, getTime);
非静态:
(*jniEnv)->CallVoidMethod(jniEnv, mTestProvider, sayHello,jstrMSG);
注意 GetXXXMethodID和 CallXXXMethod。
第一个XXX表示的是映射方法的类型,如: 静态 跟非静态
第二个XXX表示 调用方法的返回值 ,如:Void,Object,等等。(调用静态方法的时候Call后面要加Static)
详细 映射方法 和 调用方法 请参考 ,这个很重要 !
3、Java上层 关键代码
TestProvider.Java的两个方法
4、Android.mk文件 关键代码
老样子,不说了,你懂的。 如果不懂,嘎嘎,那就请点击Android.mk文件 简介
5、JNI文件夹下文件
Provider.h
Provider.c
CToJava.c
3、运行效果
1、点击 “C调用java静态方法”按钮
C成功调用了Java中的getTime方法,通过C方法打印出上层调用得到的时间,并且上层成功吐司出调用信息出来。
2、点击 “C调用java非静态方法”按钮
C成功调用了sayHello方法,并成功接收到C传递的参数,和 吐司出相对应的信息
4、C调用Java注意点
a) C映射java方法时 对应的签名
getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestProvider, "getTime","()Ljava/lang/String;");
故事情节还没发展这么快,下一章才会专门介绍下这个签名的使用
b)映射方法的时候需要区别静态和非静态GetStaticMethodID,GetMethodID
c)调用的时候也需要区分CallStaticObjectMethod,CallVoidMethod而且还需要区分返回值类型
有不理解的兄弟请留言,个人技术有限,有讲错的地方请大牛们指出,讲的不够全面的请多多包涵,谢谢,