Android在JNI中使用ByteBuffer的方法

   Android在JNI中使用ByteBuffer的方法

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

  一、ByteBuffer 定义

  在NIO中,数据的读写操作始终是与缓冲区相关联的(读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入缓冲区)

  缓冲区是定长的,基本上它只是一个列表,它的所有元素都是基本数据类型。ByteBuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且信道的读写方法只接收ByteBuffer。

  ByteBuffer有以下几种常见属性:

  mark:初始值为-1,标记索引地点;

  position:初始值为0,索引下标;

  limit:最好定义成bytebuffer的长度,即允许可读空间长度;

  capacity:缓冲区能容纳的数据元素的最大数量,创建之后无法被改变;

  二、ByteBuffer使用

  1. 创建ByteBuffer

  ① 使用allocate()创建:

  ?

1
2

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

  ② 使用数组创建:

  ?

1
2

ByteBuffer buf = ByteBuffer.wrap(byteArray);
//byteArray表示一个数组

  2. 回绕缓冲区

  ?

1

buf.flip();

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

  3. 清除缓冲区

  ?

1

buf.clear();

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

  4. ByteBuffer与byte[]交互

  ?

1
2
3
4
5
6
7

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。

  ?

1

jobject NewDirectByteBuffer(void* address, jlong capacity);

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

  ?

1

void* GetDirectBufferAddress(jobject buf);

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

  ?

1

jlong GetDirectBufferCapacity(jobject buf);

  1. Jni中调用

  Java层:

  ?

1

public final int processData(ByteBuffer data);

  Native 接口:

  ?

1

private native long native_Process(ByteBuffer data);

  Jni层:

  ?

1

static jlong native_Process(JNIEnv *env,jobject obj,jobject data);

  注意ByteBuffer在JNI层中的签名:Ljava/nio/ByteBuffer;

  2. 示例(C++):

  ?

1
2
3
4
5

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程序设计有所帮助。

时间: 2024-12-03 02:27:47

Android在JNI中使用ByteBuffer的方法的相关文章

Android在JNI中使用ByteBuffer的方法_Android

本文实例讲述了Android在JNI中使用ByteBuffer的方法.分享给大家供大家参考.具体如下: 一.ByteBuffer 定义 在NIO中,数据的读写操作始终是与缓冲区相关联的(读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入缓冲区) 缓冲区是定长的,基本上它只是一个列表,它的所有元素都是基本数据类型.ByteBuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且信道的读写方法只接收ByteBuffer. ByteBuffer有以下几

Android手机内存中文件的读写方法小结

  Android手机内存中文件的读写方法小结         这篇文章主要介绍了Android手机内存中文件的读写方法,实例总结了Android针对文件读写操作的相关技巧,非常具有实用价值,需要的朋友可以参考: 如何对手机内存中的文件数据进行读写呢? Context提供了领个方法来打开该应用程序的数据文件夹中的文件I/O流,具体如下: ? 1 FileInputStream openFileInput(String name) 打开应用程序的数据文件夹下的name文件对应的数据流 ? 1 Fi

Android系统开发中log的使用方法及简单的原理_Android

在程序开发过程中,LOG是广泛使用的用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产品运营中的事件记录.在Android系统中,提供了简单.便利的LOG机制,开发人员可以方便地使用.在平时开发过程中经常需要与log打交道,所以很有必要了解log的使用方法及简单的原理. 1.linux内核的log输出 在标准的linux内核开发过程中,使用printk,这是一个与printf输出打印齐名的函数,同样提供格式化输出功能,只是其有 打印级别且将信息保存到/proc/kmsg日志中,使用c

详解Android Material设计中阴影效果的实现方法_Android

View可以投下的阴影,一个View的elevation值决定了它的阴影的大小和绘制的顺序.可以设置一个视图的elevation,在布局中使用属性:android:elevation <TextView android:id="@+id/my_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=&quo

Android系统开发中log的使用方法及简单的原理

在程序开发过程中,LOG是广泛使用的用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产品运营中的事件记录.在Android系统中,提供了简单.便利的LOG机制,开发人员可以方便地使用.在平时开发过程中经常需要与log打交道,所以很有必要了解log的使用方法及简单的原理. 1.linux内核的log输出 在标准的linux内核开发过程中,使用printk,这是一个与printf输出打印齐名的函数,同样提供格式化输出功能,只是其有 打印级别且将信息保存到/proc/kmsg日志中,使用c

详解Android Material设计中阴影效果的实现方法

View可以投下的阴影,一个View的elevation值决定了它的阴影的大小和绘制的顺序.可以设置一个视图的elevation,在布局中使用属性:android:elevation <TextView android:id="@+id/my_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=&quo

android JNI调用SDK底层C方法

问题描述 android JNI调用SDK底层C方法 如题:因为上层没法去找到方法,只有想办法去调底层C的方法,SDK源码make出来的.so库文件可以用来做jni的调用么? 底层.c文件里面没有申明JNI,我需要如何去申明 解决方案 你这几个函数的参数,返回值都比较简单,按照JNI的规则,封装导出一下,然后就可以java来调用了 http://www.cnblogs.com/anyanran/archive/2010/11/22/ndk1.html 解决方案二: http://blog.csd

reboot-android在jni中调用system()函数

问题描述 android在jni中调用system()函数 想在android程序中实现设备的重启. android在jni(c++写的)中调用system("reboot"),但是调试时,程序执行到此无任何反应,并继续执行了下面的代码.也试过了其他方法,如:android_reboot(ANDROID_RB_RESTART,0,0); 仍然无法实现重启. 想问各位有什么好办法解决吗? 解决方案 题主可以参考源码中 关机键按下时所执行的代码,印象中是一个叫做shutdownThread

【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法

错误描述 今天使用第三方的so库时候,调用JNI方法时出现了错误.报错如下所示: 11-01 16:39:20.979 4669-4669/com.netease.xtc.cloudmusic E/art: No implementation found for void com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(android.content.Context) (tried Java_com_netease_xt