欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android在JNI中使用ByteBuffer的方法

程序员文章站 2022-03-08 17:44:46
本文实例讲述了android在jni中使用bytebuffer的方法。分享给大家供大家参考。具体如下: 一、bytebuffer 定义 在nio中,数据的读写操作始终是...

本文实例讲述了android在jni中使用bytebuffer的方法。分享给大家供大家参考。具体如下:

一、bytebuffer 定义

在nio中,数据的读写操作始终是与缓冲区相关联的(读取时信道(socketchannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入缓冲区)
缓冲区是定长的,基本上它只是一个列表,它的所有元素都是基本数据类型。bytebuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且信道的读写方法只接收bytebuffer。

bytebuffer有以下几种常见属性:

mark:初始值为-1,标记索引地点;
position:初始值为0,索引下标;
limit:最好定义成bytebuffer的长度,即允许可读空间长度;
capacity:缓冲区能容纳的数据元素的最大数量,创建之后无法被改变;

二、bytebuffer使用

1. 创建bytebuffer

① 使用allocate()创建:

bytebuffer buf = bytebuffer.allocate(length);
//length表示buf的长度

② 使用数组创建:

bytebuffer buf = bytebuffer.wrap(bytearray);
//bytearray表示一个数组

2. 回绕缓冲区

buf.flip();

这个方法用来将缓冲区准备为数据传出状态,执行以上方法后,输出通道会从数据的开头而不是末尾开始.回绕保持缓冲区中的数据不变,只是准备写入而不是读取。

3. 清除缓冲区

buf.clear();

这个方法实际上也不会改变缓冲区的数据,而只是简单的重置了缓冲区的主要索引值.不必为了每次读写都创建新的缓冲区,那样做会降低性能.相反,要重用现在的缓冲区,在再次读取之前要清除缓冲区。

4. bytebuffer与byte[]交互

byte[] bytearray = new byte[10];
bytebuffer buf = bytebuffer.wrap(bytearray);
//将数组写入buf
bytearray = new byte[buf.remaining()];
buf.get(bytearray,0,bytearray.length());
//将数据读到数组中
bytearray = new byte[buf.capacity()];

三、bytebuffer与jni交互

在java1.4版本中引入的jni有三个函数可以用于nio的直接缓冲器。一个直接字节缓冲器是一个用于字节数据的容器,java将尽力在它上面执行本机i/o操作。jni定义了三个用于nio操作的函数。

基于到存储器地址的指针以及存储器长度(容量),函数分配并且返回一个新的java.nio.bytebuffer。如果函数没有针对当前java虚拟机实现,则返回null,或者抛出一个异常。如果没有存储器可用,则将会抛出一个outofmemoryexception。

jobject newdirectbytebuffer(void* address, jlong capacity);

getdirectbufferaddress函数返回一个指向被传入的java.nio.bytebuffer对象的地址指针。如果函数尚未针对当前虚拟机实现,或者如果buf不是java.nio.bytebuffer的一个对象,又或者存储器区尚未定义,则都将返回null。

void* getdirectbufferaddress(jobject buf);

getdirectbuffercapacity函数返回被传入的java.nio.bytebuffer对象的容量(以字节计数)。如果函数没有针对当前环境实现,或者如果buf不是java.nio.bytebuffer类型的对象返回-1。

jlong getdirectbuffercapacity(jobject buf);

1. jni中调用

java层:

 public final int processdata(bytebuffer data);

native 接口:

 private native long native_process(bytebuffer data);

jni层:

static jlong native_process(jnienv *env,jobject obj,jobject data);

注意bytebuffer在jni层中的签名:ljava/nio/bytebuffer;

2. 示例(c++):

jclass cls = env->getobjectclass(obj);
jfieldid fid = env->getfieldid(cls, "data","ljava/nio/bytebuffer;");
jobject bar = env->getobjectfield(obj, fid);
pimagedata->data= (mbyte*)env->getdirectbufferaddress(bar);
//data是结构体pimagedata中的byte[];

希望本文所述对大家的android程序设计有所帮助。