本篇将介绍在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. xcode单步调试快捷键

    xcode单步调试快捷键f6,但是磨人f6是用来调节键盘亮度的,在系统偏好,键盘设置里面,做如下设置就可以了.

  2. 【转】mysql函数

    MySQL函数 MySQL数据库提供了很多函数包括: 数学函数: 字符串函数: 日期和时间函数: 条件判断函数: 系统信息函数: 加密函数: 格式化函数: 一.数学函数 数学函数主要用于处理数字,包括 ...

  3. 取distinct数据同时还取其他字段

    的 SELECT id,group_concat(distinct model) FROM tsdr_case group by model order by id

  4. 路由器wan口连接不上的问题

    路由器:tp-link:系统:win8.1:网络类型:PPPoE 克隆“当前管理PC的MAC地址”后,无法连接,将网线直接连到电脑上可以连接,所以问题一定出在路由上,经过不断探索发现问题所在,通过命令 ...

  5. include和 merge

    include和merge标记的作用主要是为了解决layout的重用问题. 比如我们有三四个Activity但是他们都要用到同一个样式的标题栏,虽然我们把一样的代码copy个三四遍也没关系,但实在是太 ...

  6. android把图片 视频 保存到相册

    //android把图片文件添加到相册 ContentResolver localContentResolver = getContentResolver(); ContentValues local ...

  7. 笨方法学python--简介

    该章提到编程新手所需的三种最重要的技术:读和写,注重细节,发现不同. 读 和 写 即熟悉代码中的各种字符. 注 重 细 节 将例子一字不差地打出来,通过实践训练自己 发 现 不 同 这个是通过长年累月 ...

  8. libevent在windows下使用步骤详解

    一 环境 官方下载地址:http://libevent.org/版本:libevent-2.0.22-stable 二 编译静态库 1 解压把上面下载到libevent-2.0.22-stable.t ...

  9. Ant 参考

    http://ant.apache.org/manual/Tasks/exec.html Exec Description Executes a system command. When the os ...

  10. UVA 571 Jugs ADD18 小白书10 数学Part1 专题

    只能往一个方向倒,如c1=3,c2=5,a b从0 0->0 5->3 2->0 2->2 0->2 5->3 4->0 4->3 1->0 1- ...