android jni c调用java,Android 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(这两个参数一定要加入)来获得,放到第二个参数即可。

785dbfa3a302232aec67730c4132e94c.png

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方法

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

Android JNI c/c++调用java 无需新建虚拟机

近期通过研究SDL源码 得出android JNI  c/c++调用java 无需新建虚拟机: 具体步骤如下 第一步获得:两个参数 JNIEnv和jclass void Java_com_Test_A ...

JNI C反射调用java方法

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

Android JNI中C和JAVA代码之间的互相调用

关于Android studio中使用NDK/JNI环境和入门:http://blog.csdn.net/quan648997767/article/details/64923143 1. C代码回调 ...

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

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

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方法呢?就需 ...

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

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

java native interface JNI 调用Java方法

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

随机推荐

jQuery获取及设置单选框、多选框、文本框内容

获取一组radio被选中项的值 var item = $('input[@name=items][@checked]').val(); 获取select被选中项的文本 var item = $(&qu ...

asp.net MVC4 lognet4 日志

asp.net MVC4 lognet4 日志 步骤: 1.引入log4net.dll 2.写配置文件 web.config 加入 如下代码 在 中加入&l ...

iOS - Swift Set		集合

前言 Set:集合 public struct Set : Hashable, CollectionType, ArrayLiteralConver ...

测试分页查询出数据并分文件导出[java工程]

package cn.shiyanjun.test; import java.util.ArrayList; import java.util.List; public class ExcelTest ...

poj 1696 Space Ant 极角排序

#include #include #include #include #inclu ...

Less 关于css hack的写法

由于工作需要,最近一直在弄css转写less,遇到最多的问题就是 hack的写法,一些IE的hack,less不支持编译: 常见的不支持的hack如下: IE的滤镜写法 \9\0    IE8部分支持 ...

linux中用户信息及密码相关知识

在linux中若修改用户信息.密码,组群信息.密码等.其实是在修改/etc/passwd,/etc/shadow,/etc/group,/etc/groupshadow等文件的内容. 这四个文件的意思 ...

OpenSuse13.2安装CUDA Toolkit 7.5

此次安装过程有点曲折,不过最后还是能成功安装,由于没细细看官方的安装文档,导致花了很多时间安装,希望此文能让想装CUDA的同学少走点弯路 1.NVIDIA Driver是否要装 刚开始要装CUDA时, ...

Java 处理图片 base64 编码的相互转换

哈喽大家好我是刘德华. 今天项目优化了一下上传头像的功能.采用 imagecropper 插件完成裁剪图片的效果. 这个插件裁剪完的图片都是 base64 加密的字符串,上传头像也就涉及到了如何把加密 ...

java应用的jar包多合一

之前开发的java程序由于依赖比较多的jar包,启动命令为" java -classpath .:lib/*.jar 主类名",这种启动方式需要指定类路径.入口类名称,并存在jar ...

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值