| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> JNI方法简介 -> 正文阅读 |
|
[移动开发]JNI方法简介 |
前言用C/C++开发android一些功能时,不可避免的需要需要java与C/C++之间进行交互,比如数据的传递等,本文对JNI的一些相关知识做一些简述,包括JavaVM,数据类型与数据传递 1.JavaVMJava语言的执行环境时Java虚拟机(JVM)是一个独立的进程,JNIEnv是当前java线程的执行环境,一个JVM中可以有多个java线程,每个java线程对应一个JNIEnv结构,JNIEnv也是一个函数表,通过函数表可以操作java的数据和方法。 2.方法调用要想实现方法的相互调用,需要做一些处理:
2)方法通过JNIEXPORT约定为此方法可以外部调用,通过JNICALL定音函数的入栈规则以及堆栈的清理规则(看代码提示,JNICALL是空,因为Linux上可以不用),此外还要标记此方法在哪个包里哪个类下面调用的,所以方法如下所示:
上述代码表示Java.javajni包下有个NativeMethod类,此类中有个getNativeString方法是标记为Native的,即表示调用C/C++方法,此方法无入口参数,返回值是String类型。所有的方法中都会JNIEnv *env,jclass clazz两个参数,是代java方法调用时自动传入的,所以对java侧的方法来说就是无入口参数。至于返回值为什么是jstring,下面会说明。 3)Java中的方法调用时需要先加载对应的so(在CMakeList定义),在static中加载:
getNativeString方法就对应与Native的getNativeString方法。 3.数据传递涉及到方法的调用,自然就会涉及到数据的传递。由于C/C++跟java对应的数据长度不同,比如int类型java恒为4个字节 ,而C/C++则跟平台有关。所以需要对应起来,在安卓中java的int类型对应C/C++的long类型,所以java对应的方法返回值是int,那么native方法对应的返回值是long。但是已经帮我们做了定义,使用时如果java方法对应的int类型那么native方法返回值应为jint类型。所以: 3.1 简单类型简单类型如int,long,char,float,boolen等对应native方法前直接加”j",即为jint,jlong,jchar,jfloat,jboolen。 3.2 简单数组类型简单数组类型是指int,float等类型的数组,对应的native层是jintArray和jfloatArray等,即添加前缀“j",同时添加后缀”Array“。 1)由java层传递到native的数组(以intArray为例),通过env->GetIntArrayElements方法获取数组指针,然后访问相关元素;也可以通过env->GetIntArrayRegion方法复制到一个数组中使用。 2)native层返回数组时(以intArray为例),通过env->NewIntArray创建数组,并通过env->SetIntArrayRegion为其复制 3.3 对象类型String和类都是对象类型,不过String有独立的处理方式,通过env->NewStringUTF方法返回String类型,通过env->GetStringUTFChars获取java传递给native的String。 对于不同的类均通过jobject类型传递,所以处理起来比较复杂: 但是由于java重载的存在,在获取相应id时要传入变量的id类型,方法的返回值类型以及入口参数。在调用获取ID的方法时(如env->GetMethodID),需要传入变量的签名,此签名就是用来标记类型的,如下所示: native返回对象类型比较类似,即先通过FindClass创建class对象,然后获取构造函数的方法ID(构造函数名称为""),然后通过env->NewObject创建对象,后续复制或者初始化可以参照上面的步骤。 3.4 对象数组对象数组都是通过jobjectArray来相互传递,对于java的ArrayList则通过普通的对象(3.4所示)去处理。传入Native的对象数组可以通过env->GetObjectArrayElement来获取内部元素,并通过普通对象的处理方式来获取或者调用方法。 4.内存释放对于简单类型如jint,jfloat等不需要手动释放,但是对象类型以及对象类型处理过程中获取的各种ID都需要手动释放掉。 5.结语 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 23:41:55- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |