源:Java层与Jni层的数组传递

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的定义:

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

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

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

首先看Native.java的定义:

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

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

三、 Direct Buffer 方式传递

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

首先看Native.java的定义:

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

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

四、 总结

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

Java层与Jni层的数组传递(转)的更多相关文章

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

    转载:http://www.linuxidc.com/Linux/2014-03/97561.htm Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是 ...

  2. Android jni 二维数组 传递

    学习Android Jni时,一个二维 整数 数组的传递花了我好长时间,在网上查的资料都不全,当然最后是成功了,写在这里是为了自己记住,当然有人搜索到并利用了我会很高兴.   in Android J ...

  3. Jni层回调java代码【转】

    本文转载自:http://www.linuxidc.com/Linux/2014-03/97562.htm JNI是Java Native Interface的缩写,是Java平台的重要特性,使得Ja ...

  4. 基于Eclipse的Android JNI层測试应用开发过程记录

    前言 本文记录一个Java层与JNI层參数与数据交互的应用程序开发过程.为实现一个功能完整的带Java与JNI的应用程序打下基础. 本文如果读者已搭建好Android的Eclipse与NDK开发环境, ...

  5. Android中关于JNI 的学习(三)在JNI层訪问Java端对象

    前面两篇文章简介了JNI层跟Java层的一些相应关系,包含方法名,数据类型和方法名称等,相信在理论层面.可以非常好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步 ...

  6. (转)java 层调用Jni(Ndk) 持久化c c++ 对象

    对于Jni(Ndk) 很多人应该都有印象,Android的ndk接触到的机会相对会比较多,本例子以android平台为例,pc端的话就以简单的windows为例, 编码完用vs 或是 gcc进行编译成 ...

  7. OpenCV向JNI层的参数转换

    九层之台,起于累土:千里之堤毁于蚁穴:成者半于九十.最近工程项目完全可以调试,却最后在 OpenCV向JNI层的参数转换 这个节点上遇到麻烦,看来得好好的思考一番,仔细寻找其中的纰漏. 一.实例 根据 ...

  8. java中Action层、Service层和Dao层的功能区分

    Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...

  9. [转]JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分

    首先这是现在最基本的分层方式,结合了SSH架构.modle层就是对应的数据库表的实体类.Dao层是使用了Hibernate连接数据库.操作数据库(增删改查).Service层:引用对应的Dao数据库操 ...

随机推荐

  1. UIImagePickerController 相关

    UIImagePickerController是系统封装好的一个导航视图控制器,使用其开发者可以十分方便的进行相机相册相关功能的调用.UIImagePickerController继承于UINavig ...

  2. 学习笔记——观察者模式Observer

    观察者模式,当事件发生时,调用相应观察者的方法进行“通知”.Subject中使用一个数据结构存储需要通知的观察者对象,执行Notify时,执行所有观察者的Update方法.

  3. Linux + Apache + PHP 环境搭建

    搭建环境: Ubuntu 15.04 Apache 2.4.16 PHP 5.6.15 1 安装Apache 先安装依赖程序(都安装在 /usr/local/ 目录下) apr-1.5.2.tar.g ...

  4. Problem H: 小火山的围棋梦想 多校训练2(小火山专场)

    题目链接:http://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1908 题意:如果'.'被'*'围起来,就把'.'变为'*'. 分析:如果是'*'直接输出, ...

  5. 介绍Python程序员常用的IDE和其它开发工具

    概述 “工欲善其事,必先利其器”,如果说编程是程序员的手艺,那么IDE就是程序员的吃饭家伙了. IDE 的全称是Integration Development Environment(集成开发环境), ...

  6. 第13章 Swing程序组件----常用布局管理器

    在Swing中,每个组件在容器中都有一个具体的位置和大小,而在容器中摆放各种组件时很难判断其具体位置和大小.布局管理器提供了Swing组件安排.展示在容器中的方法及基本的布局功能. Swing提供的常 ...

  7. centos搭建nginx环境

    1.yum install  pcre* 2.wget http://nginx.org/download/nginx-1.7.8.tar.gz 3.tar -zxvf nginx-1.7.8.tar ...

  8. linux下GBK->UTF-8文件编码批量转换脚本

    find default -type d -exec mkdir -p utf/{} \;find default -type f -exec iconv -f GBK -t UTF-8 {} -o ...

  9. C#编写Windows服务程序图文教程

    安装服务程序C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe  要安装的服务程序路径(如F:\***.exe)卸载服务程序C: ...

  10. Sasha and Array

    Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input standard inp ...