背景需求

  我们需要在JNI的C代码调用Java代码。实现原理:使用JNI提供的反射借口来反射得到Java方法,进行调用。

JNI关键方法讲解。

1. 在同一个类中,调用其他方法

  1. JNIEXPORT void JNICALL Java_cn_itcast_ndkcallback_DataProvider_callmethod1
  2. (JNIEnv * env, jobject obj){
  3. //在c代码里面调用java代码里面的方法
  4. // java 反射
  5. //1 . 找到java代码的 class文件
  6. // jclass (*FindClass)(JNIEnv*, const char*);
  7. jclass dpclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DataProvider");
  8. if(dpclazz==){
  9. LOGI("find class error");
  10. return;
  11. }
  12. LOGI("find class ");
  13.  
  14. //2 寻找class里面的方法
  15. // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
  16. jmethodID method1 = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");
  17. if(method1==){
  18. LOGI("find method1 error");
  19. return;
  20. }
  21. LOGI("find method1 ");
  22. //3 .调用这个方法
  23. // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
  24. (*env)->CallVoidMethod(env,obj,method1);
  25. }

注意: 看红色的内容,如何获得呢? 这个是函数的签名。函数签名借住命令 javap -p -s(这两个参数一定要加入)来获得,放到第二个参数即可。

注意:

1. 要加入上面的参数 -p -s

2. signature后面有时候带“;”,不要丢掉。 主要要仔细检查

示例:

  1. void notifyOnStatusReport(int32_t status)
  2. {
  3. if (curEnv != NULL && curObj != NULL) {
  4. jclass clsstring = curEnv->FindClass("com/baidu/tieba/liveSdk/publisher/LiveNativeSender");
  5. jfieldID mUsercommandCallbackEventListnerFieldId = curEnv->GetFieldID(clsstring,"mStatusEventListener","Lcom/baidu/tieba/liveSdk/publisher/OnStatusEventListener;");
  6. jobject mUsercommandCallbackEventListner = curEnv->GetObjectField(curObj,mUsercommandCallbackEventListnerFieldId);
  7.  
  8. jclass onStatusEventListenerClsstring = curEnv->FindClass("com/baidu/tieba/liveSdk/publisher/OnStatusEventListener");
  9. jmethodID onStatusReport = curEnv->GetMethodID(onStatusEventListenerClsstring, "onStatusReport",
  10. "(I)V");
  11. curEnv->CallVoidMethod(mUsercommandCallbackEventListner, onStatusReport, status);
  12. }
  13. }

这样就可以调用DataProvider中的helloFromJava方法了。

2. 上面的方法是调用的返回值为void的java方法。如果想调用其他类型的。JNI中还提供的许多其他返回类型的方法。

  1. jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
  2. jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  3. jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  4. jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
  5. jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  6. jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  7. jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
  8. jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  9. jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  10. jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
  11. jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  12. jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  13. jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
  14. jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  15. jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  16. jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
  17. jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  18. jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  19. jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
  20. jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  21. jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  22. jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;
  23. jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;
  24. jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;
  25. jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;
  26. jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;
  27. jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;
  28. void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
  29. void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
  30. void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);

3. 如果java中的方法是静态的,就需要调用GetStaticMethodID 和 CallStaticVoidMethod 方法。

  1. JNIEXPORT void JNICALL Java_cn_itcast_ndkcallback_DataProvider_callmethod4
  2. (JNIEnv * env, jobject obj){
  3. //1 . 找到java代码的 class文件
  4. // jclass (*FindClass)(JNIEnv*, const char*);
  5. jclass dpclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DataProvider");
  6. if(dpclazz==){
  7. LOGI("find class error");
  8. return;
  9. }
  10. LOGI("find class ");
  11.  
  12. //2 寻找class里面的方法
  13. // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
  14. // 注意 :如果要寻找的方法是静态的方法 那就不能直接去获取methodid
  15. //jmethodID method4 = (*env)->GetMethodID(env,dpclazz,"printStaticStr","(Ljava/lang/String;)V");
  16. // jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
  17. jmethodID method4 = (*env)->GetStaticMethodID(env,dpclazz,"printStaticStr","(Ljava/lang/String;)V");
  18. if(method4==){
  19. LOGI("find method4 error");
  20. return;
  21. }
  22. LOGI("find method4 ");
  23.  
  24. //3.调用一个静态的java方法
  25. // void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
  26. (*env)->CallStaticVoidMethod(env,dpclazz,method4,(*env)->NewStringUTF(env,"static haha in c"));
  27. }

4. 如果C调用的Java方法不在一个类中。

分析:JNI提供的方法都有两个参数:(JNIEnv *env , jobject obj)。 env是JNI提供的方法集合。 obj是上线文。下面的例子的obj不是所需要的上下午,所以要重新创建。

  1. //obj DemoActivity
  2. JNIEXPORT void JNICALL Java_cn_itcast_ndkcallback_DemoActivity_call_1dp_1method1
  3. (JNIEnv * env, jobject obj){
  4. //在c代码里面调用java代码里面的方法
  5. // java 反射
  6. //1 . 找到java代码的 class文件
  7. // jclass (*FindClass)(JNIEnv*, const char*);
  8. jclass dpclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DataProvider");
  9. if(dpclazz==){
  10. LOGI("find class error");
  11. return;
  12. }
  13. LOGI("find class ");
  14.  
  15. //2 寻找class里面的方法
  16. // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
  17. jmethodID method1 = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");
  18. if(method1==){
  19. LOGI("find method1 error");
  20. return;
  21. }
  22. LOGI("find method1 ");
  23. //3 .调用这个方法
  24. // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
  25. // jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
  26. // jobject (*AllocObject)(JNIEnv*, jclass);
  27. jobject dpobj= (*env)->AllocObject(env,dpclazz);
  28.  
  29. (*env)->CallVoidMethod(env,dpobj,method1);
  30. }

5. 提示

为了避免4中的内容,我们尽量让C要调用的Java方法在同一个类中

JNI中C调用Java方法的更多相关文章

  1. Android JNI中C调用Java方法

    背景需求 我们需要在JNI的C代码调用Java代码.实现原理:使用JNI提供的反射借口来反射得到Java方法,进行调用. JNI关键方法讲解. 1. 在同一个类中,调用其他方法 JNIEXPORT v ...

  2. JNI C反射调用java方法

    前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记.JNI开发学习之调用C方法 Android开发中调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C调用java的方法也是 ...

  3. jni中调用java方法获取当前apk的签名文件md5值

    相应的java方法: void getsign(Context context) throws Exception { PackageInfo localPackageInfo = context.g ...

  4. HAL中通过JNI调用java方法【转】

    转载请注明本文出处:http://www.cnblogs.com/xl19862005 作者:Xandy 由于工作的需要,最近一直在研究HAL.JNI.Java方法之间互调的问题,并做了如下一些记录和 ...

  5. cocos2d-x中使用JNI的调用JAVA方法

    用cocos2d-x公布Android项目时.都应该知道要用JAVA与C/C++进行交互时会涉及到JNI的操作(Java Native Interface).JNI是JAVA的一个通用接口.旨在本地化 ...

  6. Android Studio NDK开发-JNI调用Java方法

    相对于NDK来说SDK里面有更多API可以调用,有时候我们在做NDK开发的时候,需要在JNI直接Java中的方法和变量,比如callback,系统信息等.... 如何在JNI中调用Java方法呢?就需 ...

  7. java native interface JNI 调用Java方法

    在上一篇文章中介绍了JNI.以及java调用JNI.这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你能够创建Java对象,get.set 静态(static)和 实例(instanc ...

  8. C++调用JAVA方法详解

    C++调用JAVA方法详解          博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...

  9. C#调用Java方法(详细实例)

    C#可以直接引用C++的DLL和转换JAVA写好的程序.最近由于工作原因接触这方面比较多,根据实际需求,我们通过一个具体例子把一个JAVA方法转换成可以由C#直接调用的DLL C#调用c++ C#调用 ...

随机推荐

  1. eclipse控台不见

  2. jquery trigger-bind示例

    $('#btnSearch').bind('click',function(){ .....}) 然后用trigger来激活事件:$('#btnSearch').trigger('click');

  3. 关于ArcGis的二次开发-基于ArcEngine10.2(内有安装包)

    网上很少有arcgis engine10.2的安装包,在这里我把安装包链接附上,是百度云,有需要的可以自己下--http://pan.baidu.com/s/1mhIhYYG 顺带着把arcgis d ...

  4. mySql中alter table的使用

    1.修改表名:alter table 原表名 rename to 新表名; 2.新增列:alter table 表名 add column 列名 varchar(20) ; 3.删除列:alter t ...

  5. 关于redis扩展安装及使用

    11月23日,预留 http://blog.sina.com.cn/s/blog_68431a3b0102v6dz.html http://blog.csdn.net/rachel_luo/artic ...

  6. and 与 && or 与 || 的差异之处

    其实就是比较他们的优先级 // --------------------// "||" 比 "or" 的优先级高 // 表达式 (false || true)  ...

  7. leetcode 179. Largest Number 求最大组合数 ---------- java

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  8. html5高级

    Html5高级 项目回顾 Day 01 第三阶段知识体系: (1)AJAX异步请求 数据库.PHP.HTTP.原生AJAX.jQuery中的AJAX (2)HTML5高级特性 九大新特性 (3)Boo ...

  9. pvoid64 pvoid

    如果需要某一个结构体,既在kernel space用,又在user space用,如 typedef struct { PVOID data; int size; }binary,pbinary; 上 ...

  10. Immutable 详解

    Shared mutable state is the root of all evil(共享的可变状态是万恶之源) -- Pete Hunt 有人说 Immutable 可以给 React 应用带来 ...