Android's approach to using Bytebuffer in JNI

Source: Internet
Author: User

This article describes how Android uses ByteBuffer in JNI. Share with you for your reference. details as follows:

First. Definition of ByteBuffer

In NIO, the read and write operations of data are always associated with the buffer (the channel (SocketChannel) reads data into the buffer when reading, and the sent data must first be filled into the buffer in order when writing)
The buffer is fixed-length, basically it is just a list, and all its elements are basic data types. ByteBuffer is the most commonly used buffer, it provides a method to read and write other data types, and the channel read and write method only receives ByteBuffer.

ByteBuffer has the following common properties:

mark: initial value is -1, mark the index location;
position: initial value is 0, index subscript;
limit: best defined as the length of bytebuffer, that is, the length of the allowable readable space;
capacity: the maximum number of data elements that the buffer can hold, cannot be changed after creation;

Second, the use of ByteBuffer

1. Create ByteBuffer

① Create with allocate ():

ByteBuffer buf = ByteBuffer.allocate (length);
// length indicates the length of buf
② Create with array:

ByteBuffer buf = ByteBuffer.wrap (byteArray);
// byteArray represents an array
2. Wrap buffer

buf.flip ();
This method is used to prepare the buffer as the data out state. After the above method is executed, the output channel will start from the beginning of the data instead of the end. The wraparound keeps the data in the buffer unchanged, just preparing to write instead of reading.

3. Clear the buffer

buf.clear ();
This method does not actually change the data of the buffer, but simply resets the main index value of the buffer. It is not necessary to create a new buffer for each read and write, which will reduce performance. On the contrary, it must be reused The current buffer should be cleared before reading it again.

4. ByteBuffer interacts with byte []

byte [] bytearray = new byte [10];
ByteBuffer buf = ByteBuffer.wrap (bytearray);
// Write array to buf
bytearray = new byte [buf.remaining ()];
buf.get (bytearray, 0, bytearray.length ());
// Read the data into the array
bytearray = new byte [buf.capacity ()];
Third, ByteBuffer and JNI interaction

The JNI introduced in the Java 1.4 version has three functions that can be used for the direct buffer of NIO. A direct byte buffer is a container for byte data, and Java will do its best to perform native I / O operations on it. JNI defines three functions for NIO operations.

Based on the pointer to the memory address and the memory length (capacity), the function allocates and returns a new Java.nio.ByteBuffer. If the function is not implemented for the current Java virtual machine, NULL is returned, or an exception is thrown. If no memory is available, an OutOfMemoryException will be thrown.

jobject NewDirectByteBuffer (void * address, jlong capacity);
The GetDirectBufferAddress function returns an address pointer to the passed java.nio.ByteBuffer object. If the function has not been implemented for the current virtual machine, or if buf is not an object of java.nio.ByteBuffer, or the memory area has not been defined, then it will return NULL.

void * GetDirectBufferAddress (jobject buf);
The GetDirectBufferCapacity function returns the capacity (in bytes) of the java.nio.ByteBuffer object passed in. If the function is not implemented for the current environment, or if buf is not an object of type java.nio.ByteBuffer returns -1.

jlong GetDirectBufferCapacity (jobject buf);
1. Call in Jni

Java layer:

 public final int processData (ByteBuffer data);
Native interface:

 private native long native_Process (ByteBuffer data);
Jni layer:

static jlong native_Process (JNIEnv * env, jobject obj, jobject data);
Note the signature of ByteBuffer in the JNI layer: Ljava / nio / ByteBuffer;

2. Example (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 is byte [] in the structure pImageData;
Hope this article is helpful to everyone's Android programming.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.