1.创建xxx.jni包并在该包下实现一些Java的方法,和要调用的本地方法

2.实现MainActivity中的按钮点击事件—即点击按钮调用本地的方法

3.在C文件中的方法中回调Java的方法

  3.1:通过env获取字节码对象—>jclass   (*FindClass)(JNIEnv*, const char*)

    第二个参数为要回调Java方法所在类的全路径如:jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");

  3.2:通过字节码对象获取方法ID—>jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

    第二个参数是由3.1获取的字节码对象,第三个对象是要回调的Java方法名,第四个参数该Java方法签名,因为Java中有重载,需要此参数确定具体是哪个方法如:jmethodID methodId = (*env)->GetMethodID(env, claz, "helloFromJava", "()V")

    注:对应方法签名,需要到工程目录下的bin/classes目录下执行:javap -s com.rocky.jniccallbackdemo.jni.JNI(该方法所在类的全类名)

  3.3:通过字节码对象创建Java对象—>jobject (*AllocObject)(JNIEnv*, jclass);
    如:jobject obj = (*env)->AllocObject(env, claz);

注:如果本地方法和要回调的Java方法在同一个类中,则第二参数就是本地方法传过来的第二个参数,即第三步可以可以省略。

  3.4:通过Java对象回调Java方法

  调用Java的无返回值方法:void  (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...),如: (*env)->CallVoidMethod(env, clazz, methodId);

DEMO:

JNI.java

  1. public class JNI
  2. {
  3. static {
  4. System.loadLibrary("callback");
  5. }
  6. private Context mContext = null;
  7. public JNI(Context context)
  8. {
  9. this.mContext = context;
  10. }
  11. public void helloFromJava()
  12. {
  13. System.out.println("Hello From Java");
  14. }
  15. public void printString(String str)
  16. {
  17. System.out.println(str);
  18. }
  19. public void showToast(String str)
  20. {
  21. Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show();
  22. }
  23. public native void callbackVoidMethod();
  24. public native void callbackStringMethod();
  25. public native void callbackIntMethod();
  26. public native void callbackShowToastMethod();
  27. }

MainActivity.java

  1. public class MainActivity extends Activity implements OnClickListener
  2. {
  3. Context mContext = null;
  4. Button bt_callback_void = null;
  5. Button bt_callback_string = null;
  6. Button bt_callback_int = null;
  7. Button bt_callback_toast = null;
  8. JNI jni = null;
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState)
  11. {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_main);
  14. mContext = this;
  15. jni = new JNI(mContext);
  16. bt_callback_void = (Button) findViewById(R.id.bt_callback_void);
  17. bt_callback_void.setOnClickListener(this);
  18. bt_callback_int = (Button) findViewById(R.id.bt_callback_int);
  19. bt_callback_int.setOnClickListener(this);
  20. bt_callback_string = (Button) findViewById(R.id.bt_callback_string);
  21. bt_callback_string.setOnClickListener(this);
  22. bt_callback_toast = (Button) findViewById(R.id.bt_callback_toast);
  23. bt_callback_toast.setOnClickListener(this);
  24. }
  25. public int add(int x, int y)
  26. {
  27. return x + y;
  28. }
  29. @Override
  30. public void onClick(View v)
  31. {
  32. switch (v.getId())
  33. {
  34. case R.id.bt_callback_void:
  35. jni.callbackVoidMethod();
  36. break;
  37. case R.id.bt_callback_int:
  38. jni.callbackIntMethod();
  39. break;
  40. case R.id.bt_callback_string:
  41. jni.callbackStringMethod();
  42. break;
  43. case R.id.bt_callback_toast:
  44. jni.callbackShowToastMethod();
  45. break;
  46.  
  47. default:
  48. break;
  49. }
  50. }
  51. }

callback.c

  1. #include <jni.h>
  2. #include <android/log.h>
  3. #define LOG_TAG "rocky"
  4. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  5. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
  6. #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
  7. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
  8. #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
  9.  
  10. JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackVoidMethod
  11. (JNIEnv *env, jobject clazz)
  12. {
  13. //1.获取字节码对象 jclass (*FindClass)(JNIEnv*, const char*);
  14. jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");
  15. //2.通过字节码对象获取方法ID jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
  16. jmethodID methodId = (*env)->GetMethodID(env, claz, "helloFromJava", "()V");
  17. //3.通过字节码对象创建Java对象(此处因为本地方法和回调方法在同一个类中,可以省略)
  18. //4.通过Java对象回调Java方法 void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
  19. (*env)->CallVoidMethod(env, clazz, methodId);
  20. }
  21. /*
  22. * Class: com_rocky_jniccallbackdemo_jni_JNI
  23. * Method: callbackIntMethod
  24. * Signature: ()V
  25. */
  26. JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackIntMethod
  27. (JNIEnv *env, jobject clazz)
  28. {
  29. jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/MainActivity");
  30. jmethodID methodId = (*env)->GetMethodID(env, claz, "add", "(II)I");
  31. //3.通过字节码对象创建Java对象(此处为MainActivity对象) jobject (*AllocObject)(JNIEnv*, jclass);
  32. // jobject obj = (*env)->AllocObject(env, claz);
  33. //4.通过Java对象回调Java方法 void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
  34. jobject obj = (*env)->AllocObject(env, claz);
  35. jint res = (*env)->CallIntMethod(env, obj, methodId, , );
  36. LOGI("res = %d\n", res);
  37. }
  38. JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackStringMethod
  39. (JNIEnv *env, jobject clazz)
  40. {
  41. jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");
  42. jmethodID methodId = (*env)->GetMethodID(env, claz, "printString", "(Ljava/lang/String;)V");
  43. jstring result = (*env)->NewStringUTF(env, "cccccccccccccc");
  44. (*env)->CallVoidMethod(env, clazz, methodId, result);
  45. }
  46. JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackShowToastMethod
  47. (JNIEnv *env, jobject clazz)
  48. {
  49. jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");
  50. jmethodID methodId = (*env)->GetMethodID(env, claz, "showToast", "(Ljava/lang/String;)V");
  51. jstring result = (*env)->NewStringUTF(env, "rocky--------rocky");
  52. (*env)->CallVoidMethod(env, clazz, methodId, result);
  53. }

Android.mk

  1. LOCAL_PATH := $(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. LOCAL_MODULE := callback
  6. LOCAL_SRC_FILES := callback.c
  7.  
  8. LOCAL_LDLIBS += -llog
  9.  
  10. include $(BUILD_SHARED_LIBRARY)

JNI系列——C文件中的方法调用Java中方法的更多相关文章

  1. 不用static,巧用对象.方法调用java中的函数

    先生成一个对象,用"对象.方法()"的方式调用. java中的main方法是静态的,用于程序的入口,在静态方法中无法调用非静态方法,只能调用静态方法.想调用静态方法的话就要先生成该 ...

  2. C通过JNI反向调用JAVA程序方法

    JNI反向调用JAVA程序 引述:上文讲过java线程---OS线程的关系,然后C怎样反向调用JAVA程序方法是我们这篇讲的重点 1.ThreadTest中添加run()方法 2.编译ThreadTe ...

  3. 在ASP.Net环境中,当用户点击报表中的超链接时如何调用Java Script方法?

    问题描述:在ASP.Net环境中,当用户点击报表中的超链接时如何调用Java Script方法? 问题解答: 你可以在TextObject.Hyperlink对象中编写js代码(javascript: ...

  4. 第7.22节 Python中使用super调用父类的方法

    第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...

  5. vue中methods一个方法调用另外一个方法

    转自http://blog.csdn.net/zhangjing1019/article/details/77942923 vue在同一个组件内: methods中的一个方法调用methods中的另外 ...

  6. 为什么static方法中不可以调用非static方法

    Java是面向对象的语言,所有的变量,方法都是针对对象而言的.一般来说,要调用一个方法,你需要new 这个方法的对象. 什么时候用static? 如果你想要: 对于一个类的所有对象共享一个变量或者是方 ...

  7. vue methods 方法中 方法 调用 另一个方法。

    vue在同一个组件内: methods中的一个方法调用methods中的另外一个方法. 可以在调用的时候 this.$options.methods.test(); this.$options.met ...

  8. PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。

    PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...

  9. JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程

    JNI/NDK Java调用C/C++前言  通过第三篇文章讲解在实际的开发过程中Java层调用C/C++层的处理流程.其实我们在很大的业务里也需要C/C+ +层去调用Java层,这两层之间的相互调用 ...

随机推荐

  1. SpringMVC从入门到精通之第一章

    第一节 简介:SpringMVC是Spring框架的一个模块,Spring和SpringMVC无需通过中间整合层进行整合.SpringMVC是基于MVC的WEB框架.MVC设计模式在B/S下的应用: ...

  2. Simple Infinite automaton [C]

    Today I read the book Formal Language and Automaton Theory. And I learnt the infinite automaton. Her ...

  3. Docker Network containers

    Network containers Estimated reading time: 5 minutes If you are working your way through the user gu ...

  4. java 继承(下)

    1.抽象方法一定要写在抽象类中. 2.抽象类只在描述该事事务应该具备的东西. 3.抽象只能是抽象类和抽象方法. 4,抽象类没有任何抽象方法,这种类是不让创建对象. private  static

  5. Oracle之多行记录变一行记录,行变列,并排序(wmsys.wm_concat)

    原帖:http://www.cnblogs.com/nayitian/p/3231734.html wmsys.wm_concat Definition: The Oracle PL/SQL WM_C ...

  6. 如果觉得配置文件没有错,但web-dev-server总是报错,可以在hosts文件里加一行127.0.0.1 localhost

    如果觉得配置文件没有错,但web-dev-server总是报错,可以在hosts文件里加一行127.0.0.1 localhost

  7. jquery noConflict详解

    noConflict是防止其他库也用了$作为全局变量而引起的冲突,我们看看jquery是怎么做的 首先jquery在代码的开始部分定义了2个私有变量: _jQuery = window.jQuery ...

  8. js数组操作

    用 js有很久了,但都没有深究过js的数组形式.偶尔用用也就是简单的string.split(char).这段时间做的一个项目,用到数组的地方很多, 自以为js高手的自己居然无从下手,一下狠心,我学! ...

  9. Pycharm: keyboard reference

    Source: Official set ♥ Editing Ctrl + Space Basic code completion (the name of any class, method or ...

  10. CentOS上搭建Nginx + Mono 运行 asp.net

    安装步骤: 一.获取开源相关程序: 1.利用CentOS Linux系统自带的yum命令安装.升级所需的程序库: sudo -sLANG=Cyum -y install gcc gcc-c++ aut ...