Android开发实践:Java层与Jni层的数组传递

2023-10-28

http://www.linuxidc.com/Linux/2014-03/97561.htm

Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层,由Jni层的Socket代码发送出去,当然,Jni层也需要把从Socket接收到的数据流返回给Java层。我简单地总结了一下,从Java层到Jni层,从Jni层到JAVA层,各有3种传递方式,下面用代码示例简单地介绍一下。

示例代码的主要文件有两个,一个是Native.java,是Java层的类;另一个是Native.c,是JNI层的文件,关键的地方我都用注释添加到代码中了,完整的代码见博文后面的附件。

一、 从Java传递数组到Jni层

Jni层接收到Java层传递过来的byte[]数组,一般有2个函数来获取它的值,一个 GetByteArrayRegion,另一个是 GetByteArrayElements ,前者是进行值拷贝,将Java端数组的数据拷贝到本地的数组中,后者是指针的形式,将本地的数组指针直接指向Java端的数组地址,其实本质上是JVM在堆上分配的这个数组对象上增加一个引用计数,保证垃圾回收的时候不要释放,从而交给本地的指针使用,使用完毕后指针一定要记得通过ReleaseByteArrayElements进行释放,否则会产生内存泄露。

首先看Native.java的定义:

Android开发实践:Java层与Jni层的数组传递

再看看对应的native.c的实现代码:

Android开发实践:Java层与Jni层的数组传递

二、 从Jni层传递数组到Java层

把Jni层定义的数组传递到Java层,一般有两种方法,一种是通过native函数的返回值来传递,另一种是通过jni层回调java层的函数来传递,后者多用于jni的线程中。无论哪种方法,都离不开 SetByteArrayRegion 函数,该函数将本地的数组数据拷贝到了 Java 端的数组中。下面只介绍前一种方式,即通过native函数返回值的方式传递jni层的数组,回调的方式其实用法类似,就不详细介绍了。

首先看Native.java的定义:

Android开发实践:Java层与Jni层的数组传递

再看看native.c是如何实现的:

Android开发实践:Java层与Jni层的数组传递

由上述代码示例可以看出,首先通过 NewByteArray 在堆上分配数组对象,然后通过SetByteArrayRegion 把本地的数组数据拷贝到堆上分配的数组中去,然后通过返回值将分配的数组对象返回到Java层即可。对于回调的方式,这几步操作也是一样的,唯一的不同是,回调方式不是以返回值的方式将数组对象返回给Java层,而是在回调函数中,以回调函数参数的形式返回给Java层。

三、 Direct Buffer 方式传递

Java和Jni层的数组传递还有一个比较重要的方式,就是通过Direct Buffer来传递,这种方式类似于在堆上创建创建了一个Java和Jni层共享的整块内存区域,无论是Java层或者Jni层均可访问这块内存,并且Java端与Jni端同步变化,由于是采用的是共享内存的方式,因此相比于普通的数组传递,效率更高,但是由于构造/析构/维护这块共享内存的代价比较大,所以小数据量的数组建议还是采用上述方式,Direct Buffer方式更适合长期使用频繁访问的大块内存的共享。具体使用方法介绍如下:

首先看Native.java的定义:

Android开发实践:Java层与Jni层的数组传递

再看看native.c是如何实现的:

Android开发实践:Java层与Jni层的数组传递

由上述代码可以看出,其中使用起来还是很简单的,Jni层只需要通过GetDirectBufferAddress函数即可获取到这块共享的内存的地址,Direct Buffer的管理工作均由操作系统来负责。

四、 总结

关于Java与Jni层的数组传递就介绍到这里了,其实并不复杂,希望上述代码对初学者能有所帮助,有任何疑问或者不清楚的地方欢迎留言或者来信lujun.hust@gmail.com交流。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android开发实践:Java层与Jni层的数组传递 的相关文章

随机推荐

  • 深度学习-图像识别FPN(Feature Pyramid Networks)

    文章目录 一 FPN 二 FPN的整体架构 FPN应用于RPN层 四 FPN总结 一 FPN 卷积网络的一个重要特征 深层网络容易响应语义特征 浅层网络容易响应图像特征 但是到了物体检测领域 这个特征便成了一个重要的问题 高层网络虽然能响应
  • InitializingBean讲解

    InitializingBean讲解 Spring中有两种类型的Bean 一种是普通Bean 另一种是工厂Bean 即FactoryBean 工厂Bean跟普通Bean不同 其返回的对象不是指定类的一个实例 其返回的是该工厂Bean的get
  • cx_Oracle使用方法

    正确安装好cx oracle之后 要使用它来连接到oracle数据库进行操作 具体应该分3步走 第一步 导入cx Oracle 建立连接 gt gt gt import cx Oracle 导入模块 gt gt gt db cx Oracl
  • SpringBoot入门 快速创建并部署web后端

    这两天学习了springboot些框架开发 发现用它开发真的是简单便捷 就像是它的设计初衷所描述的那样 它虽然没有提出任何新的技术 但却将之前的spring技术集成了 他让spring变得更加好用 于是将最近的学习内容总结一下 分享给大家
  • 基于MATLAB的线激光三维彩色扫描仪

    暑期做的一个项目 开始并不是很熟悉 在网上查找的资料也不是很具体 但是自习学习了理论知识之后还是比较容易的做出来这个项目 现在开源整个项目 由于篇幅有限 本文适合稍微有点点基础的朋友 源码见底部 先显示下最后结果 一 硬件设计 主要有步进电
  • struts2与hibernate整合遇到的问题

    1 问题描述 今天练习struts2和hibernate整合 结果各层都写好了浏览器还出现了service实例空指针的错误 控制台只是提示没有找到什么值栈啊什么的 解决过程 查看各层代码 配置文件是否写的有问题 都没问题 后来就找是不是包的
  • 如何登录GItHub

    1 找到hosts 2 用管理员权限运行 3 打开终端 4 执行cmd 5 再执行notepad hosts 6 会自动弹出hosts 7 查找3个需要添加在hosts最后的内容 1 github com IP地址查询 https gith
  • Pandas常用函数操作示例

    一 概述 本文主要记录一些常用的pandas 操作示例 可收藏用作日常编码中的速查手册 用到的示例可以在下面的索引分类中找到 二 目录 文章目录 一 概述 二 目录 三 示例 1 pandas 创建 Series 通过 list 创建 se
  • CentOS7 学习 10 常用指令 7 压缩、解压缩

    索引 gzip 压缩 gunzip 解压 zip 压缩 unzip 解压 在项目打包发布中常用 这个和windows一样 tar zcvf xx tar gz 要压缩的文件file tar zxvf xx tar gz C 解压到的路径di
  • ELK日志收集系统

    Kibana 数据分析工具 提供数据的聚合 分析功能 数据的可视化 用图表展现数据 分析图标可进行分享 或在web应用中引用图表 Kibana汉化 docker cp kibana usr share kibana config kiban
  • 一篇“从入门到上手”的PCB设计教程

    一篇 从入门到上手 的PCB设计教程 这是一篇面向神马都不懂的小白玩家的PCB设计教程 希望能帮助大家快速上手PCB的设计 1 预备知识 1 1 常用工具 1 做图工具 Altium Designer 2 PCB板加工 嘉立创 3 元件封装
  • react的onClick自动触发等相关问题

    react分页组件遇到的问题 private getFirst const pageNo this state if pageNo gt 3 return span 首页 span else return private changePag
  • 基于openlayers的最短路径规划

    之前的文章讲到了如何构建空间数据库 矢量数据如何入库 如何构建拓扑网络 如何自定义查询函数 如何构建wms服务 本文讲解如何基于openlayers晚上最短路径规划功能 一 基于openlayers3 1 构建网页 这里只是一个简单的网页
  • idea 创建mybatis xml文件时找不到

    1 File gt Settings 如图 2 添加模板 如下图 3 添加xml模板 如下图 模板内容
  • 编译openwrt全过程(超详细)

    本教程的编译环境 win7 专业版 VMwareWorkstation6 5虚拟机 Ylmf OS 3 0 编译的过程中要保持电脑联网 搭建编译环境 应用程序 附件 终端 sudo apt get update 更新 安装编译需要的组件 s
  • 前端最新一面

    vue2 vue3 v model的区别 instance of原理 事件循环机制打印顺序 打印结果 1 3
  • 手机上编写Java程序的软件

    对于程序员来说 编写代码几乎都是在电脑上 但有时候在一些特殊情况下 没有电脑 或者不方便带电脑 这时就想 要是能在手机上写代码该多好啊 以前我也折腾过 找过许多软件 但感觉不如我意 但我并没有放弃 在浏览YouTube的时候 偶然发现了一款
  • 低功耗技术(三)UPF的使用

    UPF是一个统一的 被广泛应用的低功耗实现标准 它用一些标准的语言描述用户的低功耗设计意图 一 UPF所需要的特殊单元库 1 Level Shifter和Isolation Cell 对于多电压设计 需要用Level shifter来实现不
  • SpringBoot整合JWT和MD5实现单点登录

    1 知识点 1 1 JWT JSON Web Token JSON Web令牌 是一个开放标准 rfc7519 它定义了一种紧凑的 自包含的方式 用于在各方之间以JSON对象安全地传输信息 此信息可以验证和信任 因为它是数字签名的 jwt可
  • Android开发实践:Java层与Jni层的数组传递

    http www linuxidc com Linux 2014 03 97561 htm Android开发中 经常会在Java代码与Jni层之间传递数组 byte 一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层 由J