編輯:關於Android編程
本文實例講述了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程序設計有所幫助。
本章主要會講述如何在手機端使用HTTP協議和服務器端進行網絡交互,並對服務器返回的數據進行解析,這也是Android中最常使用到的網絡技術了,下面就讓我們一起來學習一下吧
Agenda:一張圖看Camera2框架類圖 CameraService啟動 ICameraService.cpp Camera2Client.h與Camera2Clie
Tablelayout類以行和列的形式對控件進行管理,每一行為一個TableRow對象,或一個View控件。當為TableRow對象時,可在TableRow下添加子控件,
Android提供了實現按照秒計時的API,今天就是用這個API實現簡單的倒計時。來個布局:<?xml version=1.0 encoding=utf-8