本篇将介绍在JNI编程中C调用Java实现。

源码下载地址:http://download.csdn.net/detail/xyz_lmn/4868265

关键代码:

java:

  1. public class CCallJava {
  2. public static String getTime() {
  3. Log.d("CCallJava",  "Call From C Java Static Method" +String.valueOf(System.currentTimeMillis()));
  4. return String.valueOf(System.currentTimeMillis());
  5. }
  6. public void sayHello(String msg) {
  7. Log.d("CCallJava",  "Call From C Java void Method" +String.valueOf(System.currentTimeMillis()));
  8. }
  9. }
C:
  1. #include "TestCCallJava.h"
  2. #include <android/log.h>
  3. extern JNIEnv* jniEnv;
  4. jclass TestCCallJava;
  5. jobject mTestCCallJava;
  6. jmethodID getTime;
  7. jmethodID sayHello;
  8. int GetTestCCallJavaInstance(jclass obj_class);
  9. /**
  10. * 初始化 类、对象、方法
  11. */
  12. int InitTestCCallJava() {
  13. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitTestCCallJava Begin  1" );
  14. if(jniEnv == NULL) {
  15. return 0;
  16. }
  17. if(TestCCallJava == NULL) {
  18. TestCCallJava = (*jniEnv)->FindClass(jniEnv,"com/trunkbow/ccalljava/CCallJava");
  19. if(TestCCallJava == NULL){
  20. return -1;
  21. }
  22. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitTestCCallJava Begin  2 ok" );
  23. }
  24. if (mTestCCallJava == NULL) {
  25. if (GetTestCCallJavaInstance(TestCCallJava) != 1) {
  26. (*jniEnv)->DeleteLocalRef(jniEnv, TestCCallJava);
  27. return -1;
  28. }
  29. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitTestCCallJava Begin  3 ok" );
  30. }
  31. if (getTime == NULL) {
  32. getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestCCallJava, "getTime","()Ljava/lang/String;");
  33. if (getTime == NULL) {
  34. (*jniEnv)->DeleteLocalRef(jniEnv, TestCCallJava);
  35. (*jniEnv)->DeleteLocalRef(jniEnv, mTestCCallJava);
  36. return -2;
  37. }
  38. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitTestCCallJava Begin  4 ok" );
  39. }
  40. if (sayHello == NULL) {
  41. sayHello = (*jniEnv)->GetMethodID(jniEnv, TestCCallJava, "sayHello","(Ljava/lang/String;)V");
  42. if (sayHello == NULL) {
  43. (*jniEnv)->DeleteLocalRef(jniEnv, TestCCallJava);
  44. (*jniEnv)->DeleteLocalRef(jniEnv, mTestCCallJava);
  45. (*jniEnv)->DeleteLocalRef(jniEnv, getTime);
  46. return -3;
  47. }
  48. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitTestCCallJava Begin  5 ok" );
  49. }
  50. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitTestCCallJava Begin  6" );
  51. return 1;
  52. }
  53. int GetTestCCallJavaInstance(jclass obj_class) {
  54. if(obj_class == NULL) {
  55. return 0;
  56. }
  57. jmethodID construction_id = (*jniEnv)->GetMethodID(jniEnv, obj_class,
  58. "<init>", "()V");
  59. if (construction_id == 0) {
  60. return -1;
  61. }
  62. mTestCCallJava = (*jniEnv)->NewObject(jniEnv, obj_class,
  63. construction_id);
  64. if (mTestCCallJava == NULL) {
  65. return -2;
  66. }
  67. return 1;
  68. }
  69. /**
  70. * 获取时间 ---- 调用 Java 方法
  71. */
  72. void GetTime() {
  73. if(TestCCallJava == NULL || getTime == NULL) {
  74. int result = InitTestCCallJava();
  75. if (result != 1) {
  76. return;
  77. }
  78. }
  79. jstring jstr = NULL;
  80. char* cstr = NULL;
  81. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "GetTime Begin" );
  82. jstr = (*jniEnv)->CallStaticObjectMethod(jniEnv, TestCCallJava, getTime);
  83. cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0);
  84. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Success Get Time from Java , Value = %s",cstr );
  85. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "GetTime End" );
  86. (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr);
  87. (*jniEnv)->DeleteLocalRef(jniEnv, jstr);
  88. }
  89. /**
  90. * SayHello ---- 调用 Java 方法
  91. */
  92. void SayHello() {
  93. if(TestCCallJava == NULL || mTestCCallJava == NULL || sayHello == NULL) {
  94. int result = InitTestCCallJava() ;
  95. if(result != 1) {
  96. return;
  97. }
  98. }
  99. jstring jstrMSG = NULL;
  100. jstrMSG =(*jniEnv)->NewStringUTF(jniEnv, "Hi,I'm From C");
  101. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "SayHello Begin" );
  102. (*jniEnv)->CallVoidMethod(jniEnv, mTestCCallJava, sayHello,jstrMSG);
  103. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "SayHello End" );
  104. (*jniEnv)->DeleteLocalRef(jniEnv, jstrMSG);
  105. }

关键代码说明:

 

C中定义映射的类、方法、对象

  1. jclass TestCCallJava;
  2. jobject mTestCCallJava;
  3. jmethodID getTime;
  4. jmethodID sayHello;

InitTestCCallJava()方法初始化类、方法、对象

初始化类:
  1. TestCCallJava = (*jniEnv)->FindClass(jniEnv,"com/trunkbow/ccalljava/CCallJava");

初始化对象:

  1. mTestCCallJava = (*jniEnv)->NewObject(jniEnv, obj_class,construction_id);
 

初始化方法:

静态方法:
  1. getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestCCallJava, "getTime","()Ljava/lang/String;");

非静态方法:

  1. sayHello = (*jniEnv)->GetMethodID(jniEnv, TestCCallJava, "sayHello","(Ljava/lang/String;)V");
 

C 中调用 Java的 方法

调用静态方法:

  1. jstring jstr = NULL;
  2. char* cstr = NULL;
  3. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "GetTime Begin" );
  4. jstr = (*jniEnv)->CallStaticObjectMethod(jniEnv, TestCCallJava, getTime);
  5. cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0);
  6. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Success Get Time from Java , Value = %s",cstr );
  7. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "GetTime End" );

调用非静态方法

 
  1. jstring jstrMSG = NULL;
  2. jstrMSG =(*jniEnv)->NewStringUTF(jniEnv, "Hi,I'm From C");
  3. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "SayHello Begin" );
  4. (*jniEnv)->CallVoidMethod(jniEnv, mTestCCallJava, sayHello,jstrMSG);
  5. __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "SayHello End" );

注意 GetXXXMethodID  和 CallXXXMethod 。

第一个XXX 表示的是映射方法的类型,如: 静态 跟非静态

第二个 XXX 表示 调用方法的返回值 ,如:Void,Object,等等。(调用静态方法的时候Call后面要加Static)

详细 映射方法 和 调用方法 请参考 JNI 文档 ,这个很重要 !

 
工程的其他代码可在http://download.csdn.net/detail/xyz_lmn/4868265下载
 
参考:
 
 

/**
* @author 张兴业
*  iOS入门群:83702688
*  android开发进阶群:241395671
*  我的新浪微博:@张兴业TBOW
*/

Android JNI入门第六篇——C调用Java的更多相关文章

  1. Android JNI入门第五篇——基本数据类型使用

    前面讲到了java和native数据类型,这里就开始做一下使用: 第一步:新建工程 第二部:书写 java方法: public class NativeMethod { static { System ...

  2. Android JNI入门第三篇——jni头文件分析

    一. 首先写了java文件: public class HeaderFile { private native void  doVoid(); native int doShort(); native ...

  3. Android JNI入门第四篇——Android.mk文件分析

    ndroid.mk文件是在使用NDK编译C代码时必须的文件,Android.mk文件中描述了哪些C文件将被编译且指明了如何编译.掌握Android.mk文件的编写主要是掌握其里头将要使用的一些关键字, ...

  4. Android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题

    最近在移植网络摄像机里的p2p库到android平台,需要用到jni,最近在c线程了调用java函数的时候 出现一个问题,假如在同一个线程调用java函数是没问题的,但在一个c线程了调用java函数就 ...

  5. Android JNI开发之C/C++层调用JAVA

    一.从C/C++层调用JAVA层代码(无参数调用) //在c代码里面调用java代码里面的方法 // java 反射 // 1 . 找到java代码的 class文件 // jclass (*Find ...

  6. Android入门第六篇之ListView (一)

    本文来自http://blog.csdn.net/hellogv/ ListView是一个经经常使用到的控件,ListView里面的每一个子项Item能够使一个字符串,也能够是一个组合控件.先说说Li ...

  7. # hadoop入门第六篇:Hive实例

    前言   前面已经讲了如何部署在hadoop集群上部署hive,现在我们就做一个很小的实例去熟悉HIVE QL.使用的数据是视频播放数据包括视频编码,播放设备编码,用户账号编码等,我们在这个数据基础上 ...

  8. Visualforce入门第六篇_2017.3.1

    Visualforce实现过滤.数据列表显示.分页功能 可以参考salesforce官网开发文档:https://trailhead.salesforce.com/modules/visualforc ...

  9. JavaMail入门第五篇 解析邮件

    上一篇JavaMail入门第四篇 接收邮件中,控制台打印出的内容,我们无法阅读,其实,让我们自己来解析一封复杂的邮件是很不容易的,邮件里面格式.规范复杂得很.不过,我们所用的浏览器内置了解析各种数据类 ...

随机推荐

  1. java中的Unicode中文转义

    String ori = "\u5e7f\u4e1c"; public static String convertUnicode(String ori) { char aChar; ...

  2. linux centos下安装g++

    1.查看是否安装 g++ -v 2.命令直接安装 yum install gcc-c++ 3.提示你找不到g++安装包,执行下面命令 yum install gcc-c++ libstdc++-dev ...

  3. JS-日期框、下拉框、全选复选框

    <!-- 下拉框 --><link rel="stylesheet" href="static/ace/css/chosen.css" /&g ...

  4. 【java】基础中的杂乱总结(二)

    1 内部类进阶 package package8; //原则:先用内部类写 之后由于内部类匿名无法引用 用其继承的父类或实现的接口名 //再复写所有的抽象方法即可(是所有,否者还是抽象的,无法创建对象 ...

  5. OpenGL---------光照的基本知识

    从生理学的角度上讲,眼睛之所以看见各种物体,是因为光线直接或间接的从它们那里到达了眼睛.人类对于光线强弱的变化的反应,比对于颜色变化的反应来得灵敏.因此对于人类而言,光线很大程度上表现了物体的立体感. ...

  6. Hibernate 系列教程17-查询缓存

    在二级缓存配置成功的基础上进行查询缓存配置 Product public class Product { private Long id; private String name; Product.h ...

  7. C/C++ kubetu

    reference sign & use predefine in c, but const in c++

  8. MySQL操作失误导致mysql数据库查看不了

    使用  show databases; +--------------------+| Database           |+--------------------+| information_ ...

  9. Node.js学习 - Install and Configure

    平台:Windows 官网:https://nodejs.org/en/ 下载安装 CMD中运行 1 交互模式 2 命令模式 模块安装 - NPM npm install express #当前目录安 ...

  10. Kth order statistcs

    Selection: selection is a trivial problem if the input numbers are sorted. If we use a sorting algor ...