本篇将介绍在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. NSNotificationCenter消息通信机制

    作用:NSNotificationCenter是专门供程序中不同类间的消息通信而设置的. 注册通知:即要在什么地方接受消息 [[NSNotificationCenter defaultCenter] ...

  2. 天津工业大学CST专业培养方案

    第二学期 网页设计基础 计算机前沿技术 大学生心理健康与人生发展 高级语言程序设计II 思想道德修养与法律基础 职业生涯规划 大学英语二级(A) 大学物理(理三1) 线性代数 高等数学(理一2) 体育 ...

  3. MySQL源码安装(centos)

    1.去MySQL官网下载源码包 地址:http://dev.mysql.com/downloads/mysql/ 下载完后需要检查文件的MD5,以确认是否从官网下载的原版本(以防被人篡改过该软件) 使 ...

  4. shell中 if else以及大于、小于、等于逻辑表达式介绍

    比如比较字符串.判断文件是否存在及是否可读等,通常用"[]"来表示条件测试. 注意:这里的空格很重要.要确保方括号的空格.笔者就曾因为空格缺少或位置不对,而浪费好多宝贵的时间. i ...

  5. innerHTML,innerText,outerHTML,outerText,value浅析

    首先是一个例子: <div id= "aa">0<br/>0<span>11</span>22</div><inp ...

  6. 清除number输入框的上下箭头

    <input type="number"/> 在chrome,firefox,safari浏览器上输入框右侧会有上下箭头 方法1: <input type=&qu ...

  7. layer弹出层

    最近因为项目要求做了一个layer弹出层demo,先看效果图 好了,现在开始上代码 index.jsp <%@ page language="java" import=&qu ...

  8. Android Matrix类以及ColorMatri

    引自:http://www.chinabaike.com/t/37396/2014/0624/2556217.html Android Matrix类以及ColorMatrix类详解 最近在系统学习了 ...

  9. OpenGL—Android 开机动画源码分析二

    引自http://blog.csdn.net/luoshengyang/article/details/7691321/ BootAnimation类的成员函数的实现比较长,我们分段来阅读: 第三个开 ...

  10. mysql 初始化时root无密码

    修改密码 update user set password=PASSWORD('123456') where User='root'; 添加用户设置权限 grant select,insert,upd ...