1、编写native方法(java2c)和非native方法(c2java):

  1. package com.example.provider;
  2.  
  3. public class CallbackJava {
  4.  
  5. // C调用java空方法
  6. public void helloFromJava() {
  7.  
  8. System.out.println("hello from java");
  9. }
  10.  
  11. // C调用java中的带两个int参数的方法
  12. public int Add(int x, int y) {
  13. int result = x + y;
  14. System.out.println("java result=" + result);
  15. return result;
  16. }
  17.  
  18. // C调用java中参数为string的方法
  19. public void printString(String s) {
  20. System.out.println("java " + s);
  21. }
  22.  
  23. //静态方法
  24. public static void printStaticStr(String s) {
  25. System.out.println("java static-> " + s);
  26. }
  27.  
  28. // 让c代码调用对应的java代码
  29. public native void callHelloFromJava();
  30.  
  31. public native void callAdd();
  32.  
  33. public native void callPrintString();
  34.  
  35. // 调用一个静态的c代码
  36. public native void callPrintStaticStr();
  37. }

2、通过javah命令生成签名,通过javap命令生产native方法签名:

  

3、c代码

  1. FindClass:找到java中的类文件
  1. GetMethodID:根据类和方法签名找到要调用的方法。
  1. #include <stdio.h>
  2. #include <jni.h>
  3. #include <malloc.h>
  4. #include "com_example_provider_CallbackJava.h";
  5. #include "com_example_jni_MainActivity.h";
  6.  
  7. #include <android/log.h>
  8. #define LOG_TAG "System.out.c"
  9. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  10. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
  11.  
  12. jmethodID getMethodId(JNIEnv * env, char* methodname, char* signname) {
  13. jclass jclazz = (*env)->FindClass(env, "com/example/provider/CallbackJava");
  14. if (jclazz == ) {
  15. LOGD("class not find ");
  16. return;
  17. }
  18. //2、找class中方法的id,第三个参数方法名称,第四个参数该方法对应的签名
  19. jmethodID methodid = (*env)->GetMethodID(env, jclazz, methodname, signname);
  20. if (methodid == ) {
  21. LOGD("method not find ");
  22. return;
  23. }
  24. return methodid;
  25. }
  26.  
  27. JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callHelloFromJava
  28. (JNIEnv * env, jobject obj) {
  29. //1、 找java中的class文件
  30. //第二个参数是类名的(包名)
  31. jclass jclazz = (*env)->FindClass(env,"com/example/provider/CallbackJava");
  32. if(jclazz==) {
  33. LOGD("class not find ");
  34. return;
  35. }
  36. //2、找class中方法的id,第三个参数方法名称,第四个参数该方法对应的签名
  37. jmethodID methodid = (*env)->GetMethodID(env, jclazz,"helloFromJava","()V");
  38. if(methodid==) {
  39. LOGD("helloFromJava method not find ");
  40. return;
  41. }
  42. //3、调用方法
  43. //void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
  44. (*env)->CallVoidMethod(env,obj,methodid);
  45. }
  46.  
  47. JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callAdd
  48. (JNIEnv *env, jobject obj) {
  49. jmethodID mid = getMethodId(env,"Add","(II)I");
  50. int result = (*env)->CallIntMethod(env, obj, mid,,);
  51. LOGD("c to java add: d%",result);
  52. }
  53.  
  54. JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callPrintString
  55. (JNIEnv *env, jobject obj) {
  56. LOGD("c to java callPrintString start ");
  57. jmethodID mid = getMethodId(env,"printString","(Ljava/lang/String;)V");
  58. (*env)->CallVoidMethod(env, obj, mid,(*env)->NewStringUTF(env," call printString finish"));
  59. LOGD("c to java callPrintString finish ");
  60. }
  61.  
  62. JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callPrintStaticStr
  63. (JNIEnv *env, jobject obj) {
  64. jclass jclazz = (*env)->FindClass(env, "com/example/provider/CallbackJava");
  65. if (jclazz == ) {
  66. LOGD("class not find ");
  67. return;
  68. }
  69. //静态方法调用GetStaticMethodID 和 CallStaticXXXMethod
  70. jmethodID methodid = (*env)->GetStaticMethodID(env, jclazz, "printStaticStr", "(Ljava/lang/String;)V");
  71. if (methodid == ) {
  72. LOGD("printStaticStr method not find ");
  73. return;
  74. }
  75. (*env)->CallStaticVoidMethod(env, jclazz, methodid,(*env)->NewStringUTF(env,"static hello java"));
  76.  
  77. }
  78.  
  79. JNIEXPORT void JNICALL Java_com_example_jni_MainActivity_callProvider
  80. (JNIEnv *env, jobject obj){
  81. jclass jclazz = (*env)->FindClass(env,"com/example/provider/CallbackJava");
  82. if(jclazz==) {
  83. LOGD("class not find ");
  84. return;
  85. }
  86. jmethodID methodid = (*env)->GetMethodID(env, jclazz,"helloFromJava","()V");
  87. if(methodid==) {
  88. LOGD("helloFromJava method not find ");
  89. return;
  90. }
  91. //创建一个CallbackJava对象
  92. jobject jobj =(*env)->AllocObject(env, jclazz);
  93. (*env)->CallVoidMethod(env,jobj,methodid);
  94.  
  95. }

4、编译多个c文件可以用空格分开

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_MODULE :=Hello
  4. #LOCAL_SRC_FILES :=Hello.c
  5. LOCAL_SRC_FILES :=CallbackJava.c Hello.c
  6. LOCAL_LDLIBS += -llog
  7. include $(BUILD_SHARED_LIBRARY)

参考http://www.open-open.com/lib/view/open1359700820369.html

  1.  

Android学习笔记_JNI_c调用java代码的更多相关文章

  1. 六、Android学习笔记_JNI_c调用java代码

    1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // ...

  2. JNI学习笔记_C调用Java

    一.笔记 1.C调用Java中的方法,参考jni.pdf pg97可以参考博文:http://blog.csdn.net/lhzjj/article/details/26470999步骤: a. 创建 ...

  3. android Webview 实现js调用java代码实现Activity跳转

    今天有了一个需求,在android里webview加载的html页面,要求点击html页面的按钮实现Activity的跳转. 咱是是菜鸟,webview的接触不多,于是就和度娘来了次亲密接触.在其中也 ...

  4. Android学习笔记(9):使用XML文件和Java代码控制UI界面

    Android推荐使用XML文件设置UI界面.然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller.是模型(model)-视图(view)-控制 ...

  5. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

  6. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

  7. 【转】 Pro Android学习笔记(七七):服务(2):Local Service

    目录(?)[-] Local service代码 调用Local ServiceLocal Service client代码 AndroidManifestxml定义Serviceacitivty的l ...

  8. 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

    目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...

  9. 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单

    目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...

随机推荐

  1. ElasticSearch mapping中字段属性总结

  2. [實現DDD] 第11章 工廠

    創建過程中須考慮一些重要細節, 否則所創建的聚合將處於不正確的狀態, 使用適當的工廠方法可以確保這一點, 而客戶端只需輸入基本的參數(通常是值對象), 另外, 工廠能更好地表達出通用語言, 使團隊成員 ...

  3. 白话SpringCloud | 第三章:服务注册与发现(Eureka)-下

    前言 上一章节,讲解了在单机模式下的服务注册与发现的相关知识点及简单示例.而在实际生产或者在这种微服务架构的分布式环境中,需要考虑发生故障时,各组件的高可用.而其实高可用,我的简单粗俗理解就是,通过系 ...

  4. Javascript怎么跳出循环,嵌套循环。

    今天要实现一个功能,在数组a中的每一项,对应数组b中的每一项,如果对应上了就给数组b的checked增加ture属性,如果查找不到就给数组b的checked增加false属性. 如果有哪里写的不对欢迎 ...

  5. C# HashTable 使用用法详解

    C#中如何操作HashTable类呢?本文将给你答案,哈希表(Hashtable)简述在.NET Framework中, 一,Hashtable是System.Collections命名空间提供的一个 ...

  6. 利用JS提交表单的几种方法和验证(必看篇)

    第一种方式:表单提交,在form标签中增加onsubmit事件来判断表单提交是否成功 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <scr ...

  7. 解决python3缺少zlib的问题

    解决python3缺少zlib的问题 Table of Contents 1. 安装zlib 2. 重新编译安装python 3. 补充说明 在使用python3运行spark时,报缺少zlib的错误 ...

  8. for ...in 、for each ...in、 for...of(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of)

    1.for in for...in语句以任意顺序遍历一个对象的可枚举性.对于每个不同的属性,语句都会被执行. 语法 for (variable in object) {...} variable 在每 ...

  9. angular怎么样注销事件

    angular怎么样注销事件 $scope.$on("$destroy", function() { //清除配置,不然scroll会重复请求 }) 在Controller中监听$ ...

  10. 超级表格:要山寨Excel,还是与之Say Byebye?

    创业产品难免被人拿来与现有的知名产品比较,创业者也喜欢把自己的产品与现有的知名产品比较. 我,超级表格创始人,对此有话说. 当我要在各种场合描述超级表格是什么时,也纠结过. 向用户描述时,说超级表格类 ...