背景需求

我们需要在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方法

背景需求 我们需要在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 ...

android jni c调用java,Android JNI中C调用Java方法相关推荐

  1. java调用包中的类_java调用另一个包中的类的方法

    java调用另一个包中的类的方法 发布时间:2020-05-18 15:04:40 来源:亿速云 阅读:199 作者:小新 今天小编给大家分享的是java调用另一个包中的类的方法,相信很多人都不太了解 ...

  2. Java的Map中的map.keySet()方法

    参考: java 常用的数据结构 一:Java的Map中的map.keySet()方法 该方法返回map中所有key值的列表. 今天再代码中看到了Map集合中的HashMap的map.keySet() ...

  3. java有push方法么_[Java教程]js中push和join方法使用介绍

    [Java教程]js中push和join方法使用介绍 0 2013-10-09 07:00:17 push和join方法想必大家并不陌生吧,在本文将为大家详细介绍下js中的push和join方法的使用 ...

  4. java窗体中添加图片_在java窗体程序中添加图片的方法

    在java窗体程序中添加图片的方法 发布时间:2020-06-16 11:24:13 来源:亿速云 阅读:148 作者:Leah 这篇文章主要为大家详细介绍了在java窗体程序中添加图片的方法,图文详 ...

  5. java删除数组中重复元素的方法

    java删除数组中重复元素的方法 方法一:for双循环 方法二:利用HashMap,储存元素 方法一:for双循环 1.声明int类型index,该数即可为不重复元素下标,还可统计数组中不重复元素的个 ...

  6. android json mysql_Android通过json向MySQL中读写数据的方法详解【写入篇】

    本文实例讲述了Android通过json向MySQL中写入数据的方法.,具体如下: 先说一下如何通过json将Android程序中的数据上传到MySQL中: 首先定义一个类JSONParser.Jav ...

  7. unity调用普通java类_Unity中C#和Java的相互调用实例代码

    1.通过C#调用Java的方法: 在C#中添加调用的一些代码,利用Unity提供的一些接口实现调用Java! private const string JAVA_CLASS_Name = " ...

  8. android json mysql_Android通过json向MySQL中读写数据的方法详解【读取篇】

    本文实例讲述了Android通过json向MySQL中读取数据的方法.分享给大家供大家参考,具体如下: 首先 要定义几个解析json的方法parseJsonMulti,代码如下: private vo ...

  9. java中调用数组参数_java中如何调用带有数组类型参数的存储过程

    java中如何调用带有数组类型参数的存储过程 关注:95  答案:3  mip版 解决时间 2021-01-28 00:39 提问者万丈深渊 2021-01-27 14:00 不知道java中java ...

  10. html如何调用特殊字体,网页中如何调用一些特殊字体或艺术字体?

    在国内,中文网站显示的字体主要是以微软雅黑或宋体为主,而英文网站上显示的字体就丰富多样,毕竟英文字体类型容量比较小,网页加载比较快.网站上由于不同用户对特殊字体或艺术字体显示样式的青睐,网页上会调用用 ...

最新文章

  1. Google的面试题长啥样?看完被吊打!
  2. 如何共享自己的mysql
  3. 【Java学习笔记之二十八】深入了解Java8新特性
  4. 音视频技术开发周刊 | 155
  5. 对现代C++的一点看法
  6. android 添加随意拖动的桌面悬浮窗口,android 添加随意拖动的桌面悬浮窗口
  7. 这样的快速分时界面怎么样?
  8. cat 查看文件内容,默认输出到屏幕
  9. zmap zgrab 使用
  10. html5 js打开新页面,当前页面打开多个新页面的js (很流畅)
  11. java一个字符几个字节_Java 语言中一个字符占几个字节?
  12. 摄像头视场角-对角线视场角-水平视场角
  13. Android 中的长度单位详解(dp、sp、px、in、pt、mm)具体解释与换算
  14. c# NPOI 导出Excel 冻结窗格
  15. 计算机课堂小游戏活跃气氛,活跃气氛的70个小游戏 比较嗨的暖场游戏
  16. uniapp小程序src引用服务器图片时全局变量与图片路径拼接
  17. java 四舍六入五成双
  18. BZOJ 3168: [Heoi2013]钙铁锌硒维生素
  19. OneNote重装或升级版本后如何同步之前的在线笔记?
  20. 计算机网络-超网聚合(子网合并)

热门文章

  1. php 写聊天室源码,php写的简易聊天室代码
  2. 学习计算机编程(IT、偏网站开发)的参考学习网址syk
  3. 中间件是什么意思?中间件技术简介
  4. 【基于MATLAB 的VQ声纹识别系统】
  5. QT学习:制作树形列表菜单
  6. 矢量图svg转png的简单方法
  7. 个人成长(学习方法)
  8. 我的Ubuntu软件清单
  9. 将caj转换成pdf
  10. java双重循环去重_java 中 list集合去重