JNI中C调用Java方法
背景需求
我们需要在JNI的C代码调用Java代码。实现原理:使用JNI提供的反射借口来反射得到Java方法,进行调用。
JNI关键方法讲解。
1. 在同一个类中,调用其他方法
- JNIEXPORT void JNICALL Java_cn_itcast_ndkcallback_DataProvider_callmethod1
- (JNIEnv * env, jobject obj){
- //在c代码里面调用java代码里面的方法
- // java 反射
- //1 . 找到java代码的 class文件
- // jclass (*FindClass)(JNIEnv*, const char*);
- jclass dpclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DataProvider");
- if(dpclazz==){
- LOGI("find class error");
- return;
- }
- LOGI("find class ");
- //2 寻找class里面的方法
- // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
- jmethodID method1 = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");
- if(method1==){
- LOGI("find method1 error");
- return;
- }
- LOGI("find method1 ");
- //3 .调用这个方法
- // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
- (*env)->CallVoidMethod(env,obj,method1);
- }
注意: 看红色的内容,如何获得呢? 这个是函数的签名。函数签名借住命令 javap -p -s(这两个参数一定要加入)来获得,放到第二个参数即可。
注意:
1. 要加入上面的参数 -p -s
2. signature后面有时候带“;”,不要丢掉。 主要要仔细检查
示例:
- void notifyOnStatusReport(int32_t status)
- {
- if (curEnv != NULL && curObj != NULL) {
- jclass clsstring = curEnv->FindClass("com/baidu/tieba/liveSdk/publisher/LiveNativeSender");
- jfieldID mUsercommandCallbackEventListnerFieldId = curEnv->GetFieldID(clsstring,"mStatusEventListener","Lcom/baidu/tieba/liveSdk/publisher/OnStatusEventListener;");
- jobject mUsercommandCallbackEventListner = curEnv->GetObjectField(curObj,mUsercommandCallbackEventListnerFieldId);
- jclass onStatusEventListenerClsstring = curEnv->FindClass("com/baidu/tieba/liveSdk/publisher/OnStatusEventListener");
- jmethodID onStatusReport = curEnv->GetMethodID(onStatusEventListenerClsstring, "onStatusReport",
- "(I)V");
- curEnv->CallVoidMethod(mUsercommandCallbackEventListner, onStatusReport, status);
- }
- }
这样就可以调用DataProvider中的helloFromJava方法了。
2. 上面的方法是调用的返回值为void的java方法。如果想调用其他类型的。JNI中还提供的许多其他返回类型的方法。
- jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
- jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
- jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
- jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
- jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
- jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
- jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
- jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;
- jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;
- jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;
- jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;
- jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;
- jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;
- void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
- void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
3. 如果java中的方法是静态的,就需要调用GetStaticMethodID 和 CallStaticVoidMethod 方法。
- JNIEXPORT void JNICALL Java_cn_itcast_ndkcallback_DataProvider_callmethod4
- (JNIEnv * env, jobject obj){
- //1 . 找到java代码的 class文件
- // jclass (*FindClass)(JNIEnv*, const char*);
- jclass dpclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DataProvider");
- if(dpclazz==){
- LOGI("find class error");
- return;
- }
- LOGI("find class ");
- //2 寻找class里面的方法
- // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
- // 注意 :如果要寻找的方法是静态的方法 那就不能直接去获取methodid
- //jmethodID method4 = (*env)->GetMethodID(env,dpclazz,"printStaticStr","(Ljava/lang/String;)V");
- // jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
- jmethodID method4 = (*env)->GetStaticMethodID(env,dpclazz,"printStaticStr","(Ljava/lang/String;)V");
- if(method4==){
- LOGI("find method4 error");
- return;
- }
- LOGI("find method4 ");
- //3.调用一个静态的java方法
- // void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
- (*env)->CallStaticVoidMethod(env,dpclazz,method4,(*env)->NewStringUTF(env,"static haha in c"));
- }
4. 如果C调用的Java方法不在一个类中。
分析:JNI提供的方法都有两个参数:(JNIEnv *env , jobject obj)。 env是JNI提供的方法集合。 obj是上线文。下面的例子的obj不是所需要的上下午,所以要重新创建。
- //obj DemoActivity
- JNIEXPORT void JNICALL Java_cn_itcast_ndkcallback_DemoActivity_call_1dp_1method1
- (JNIEnv * env, jobject obj){
- //在c代码里面调用java代码里面的方法
- // java 反射
- //1 . 找到java代码的 class文件
- // jclass (*FindClass)(JNIEnv*, const char*);
- jclass dpclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DataProvider");
- if(dpclazz==){
- LOGI("find class error");
- return;
- }
- LOGI("find class ");
- //2 寻找class里面的方法
- // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
- jmethodID method1 = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");
- if(method1==){
- LOGI("find method1 error");
- return;
- }
- LOGI("find method1 ");
- //3 .调用这个方法
- // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
- // jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
- // jobject (*AllocObject)(JNIEnv*, jclass);
- jobject dpobj= (*env)->AllocObject(env,dpclazz);
- (*env)->CallVoidMethod(env,dpobj,method1);
- }
5. 提示
为了避免4中的内容,我们尽量让C要调用的Java方法在同一个类中
JNI中C调用Java方法的更多相关文章
- Android JNI中C调用Java方法
背景需求 我们需要在JNI的C代码调用Java代码.实现原理:使用JNI提供的反射借口来反射得到Java方法,进行调用. JNI关键方法讲解. 1. 在同一个类中,调用其他方法 JNIEXPORT v ...
- JNI C反射调用java方法
前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记.JNI开发学习之调用C方法 Android开发中调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C调用java的方法也是 ...
- jni中调用java方法获取当前apk的签名文件md5值
相应的java方法: void getsign(Context context) throws Exception { PackageInfo localPackageInfo = context.g ...
- HAL中通过JNI调用java方法【转】
转载请注明本文出处:http://www.cnblogs.com/xl19862005 作者:Xandy 由于工作的需要,最近一直在研究HAL.JNI.Java方法之间互调的问题,并做了如下一些记录和 ...
- cocos2d-x中使用JNI的调用JAVA方法
用cocos2d-x公布Android项目时.都应该知道要用JAVA与C/C++进行交互时会涉及到JNI的操作(Java Native Interface).JNI是JAVA的一个通用接口.旨在本地化 ...
- Android Studio NDK开发-JNI调用Java方法
相对于NDK来说SDK里面有更多API可以调用,有时候我们在做NDK开发的时候,需要在JNI直接Java中的方法和变量,比如callback,系统信息等.... 如何在JNI中调用Java方法呢?就需 ...
- java native interface JNI 调用Java方法
在上一篇文章中介绍了JNI.以及java调用JNI.这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你能够创建Java对象,get.set 静态(static)和 实例(instanc ...
- C++调用JAVA方法详解
C++调用JAVA方法详解 博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...
- C#调用Java方法(详细实例)
C#可以直接引用C++的DLL和转换JAVA写好的程序.最近由于工作原因接触这方面比较多,根据实际需求,我们通过一个具体例子把一个JAVA方法转换成可以由C#直接调用的DLL C#调用c++ C#调用 ...
随机推荐
- eclipse控台不见
- jquery trigger-bind示例
$('#btnSearch').bind('click',function(){ .....}) 然后用trigger来激活事件:$('#btnSearch').trigger('click');
- 关于ArcGis的二次开发-基于ArcEngine10.2(内有安装包)
网上很少有arcgis engine10.2的安装包,在这里我把安装包链接附上,是百度云,有需要的可以自己下--http://pan.baidu.com/s/1mhIhYYG 顺带着把arcgis d ...
- mySql中alter table的使用
1.修改表名:alter table 原表名 rename to 新表名; 2.新增列:alter table 表名 add column 列名 varchar(20) ; 3.删除列:alter t ...
- 关于redis扩展安装及使用
11月23日,预留 http://blog.sina.com.cn/s/blog_68431a3b0102v6dz.html http://blog.csdn.net/rachel_luo/artic ...
- and 与 && or 与 || 的差异之处
其实就是比较他们的优先级 // --------------------// "||" 比 "or" 的优先级高 // 表达式 (false || true) ...
- leetcode 179. Largest Number 求最大组合数 ---------- java
Given a list of non negative integers, arrange them such that they form the largest number. For exam ...
- html5高级
Html5高级 项目回顾 Day 01 第三阶段知识体系: (1)AJAX异步请求 数据库.PHP.HTTP.原生AJAX.jQuery中的AJAX (2)HTML5高级特性 九大新特性 (3)Boo ...
- pvoid64 pvoid
如果需要某一个结构体,既在kernel space用,又在user space用,如 typedef struct { PVOID data; int size; }binary,pbinary; 上 ...
- Immutable 详解
Shared mutable state is the root of all evil(共享的可变状态是万恶之源) -- Pete Hunt 有人说 Immutable 可以给 React 应用带来 ...