Android在JNI中使用ByteBuffer的方法
本文實例講述了Android在JNI中使用ByteBuffer的方法。分享給大家供大家參考。具體如下:
一、ByteBuffer 定義
在NIO中,數(shù)據(jù)的讀寫操作始終是與緩沖區(qū)相關(guān)聯(lián)的(讀取時信道(SocketChannel)將數(shù)據(jù)讀入緩沖區(qū),寫入時首先要將發(fā)送的數(shù)據(jù)按順序填入緩沖區(qū))
緩沖區(qū)是定長的,基本上它只是一個列表,它的所有元素都是基本數(shù)據(jù)類型。ByteBuffer是最常用的緩沖區(qū),它提供了讀寫其他數(shù)據(jù)類型的方法,且信道的讀寫方法只接收ByteBuffer。
ByteBuffer有以下幾種常見屬性:
mark:初始值為-1,標記索引地點;
position:初始值為0,索引下標;
limit:最好定義成bytebuffer的長度,即允許可讀空間長度;
capacity:緩沖區(qū)能容納的數(shù)據(jù)元素的最大數(shù)量,創(chuàng)建之后無法被改變;
二、ByteBuffer使用
1. 創(chuàng)建ByteBuffer
① 使用allocate()創(chuàng)建:
ByteBuffer buf = ByteBuffer.allocate(length); //length表示buf的長度
② 使用數(shù)組創(chuàng)建:
ByteBuffer buf = ByteBuffer.wrap(byteArray); //byteArray表示一個數(shù)組
2. 回繞緩沖區(qū)
buf.flip();
這個方法用來將緩沖區(qū)準備為數(shù)據(jù)傳出狀態(tài),執(zhí)行以上方法后,輸出通道會從數(shù)據(jù)的開頭而不是末尾開始.回繞保持緩沖區(qū)中的數(shù)據(jù)不變,只是準備寫入而不是讀取。
3. 清除緩沖區(qū)
buf.clear();
這個方法實際上也不會改變緩沖區(qū)的數(shù)據(jù),而只是簡單的重置了緩沖區(qū)的主要索引值.不必為了每次讀寫都創(chuàng)建新的緩沖區(qū),那樣做會降低性能.相反,要重用現(xiàn)在的緩沖區(qū),在再次讀取之前要清除緩沖區(qū)。
4. ByteBuffer與byte[]交互
byte[] bytearray = new byte[10]; ByteBuffer buf = ByteBuffer.wrap(bytearray); //將數(shù)組寫入buf bytearray = new byte[buf.remaining()]; buf.get(bytearray,0,bytearray.length()); //將數(shù)據(jù)讀到數(shù)組中 bytearray = new byte[buf.capacity()];
三、ByteBuffer與JNI交互
在Java1.4版本中引入的JNI有三個函數(shù)可以用于NIO的直接緩沖器。一個直接字節(jié)緩沖器是一個用于字節(jié)數(shù)據(jù)的容器,Java將盡力在它上面執(zhí)行本機I/O操作。JNI定義了三個用于NIO操作的函數(shù)。
基于到存儲器地址的指針以及存儲器長度(容量),函數(shù)分配并且返回一個新的Java.nio.ByteBuffer。如果函數(shù)沒有針對當前Java虛擬機實現(xiàn),則返回NULL,或者拋出一個異常。如果沒有存儲器可用,則將會拋出一個OutOfMemoryException。
jobject NewDirectByteBuffer(void* address, jlong capacity);
GetDirectBufferAddress函數(shù)返回一個指向被傳入的java.nio.ByteBuffer對象的地址指針。如果函數(shù)尚未針對當前虛擬機實現(xiàn),或者如果buf不是java.nio.ByteBuffer的一個對象,又或者存儲器區(qū)尚未定義,則都將返回NULL。
void* GetDirectBufferAddress(jobject buf);
GetDirectBufferCapacity函數(shù)返回被傳入的java.nio.ByteBuffer對象的容量(以字節(jié)計數(shù))。如果函數(shù)沒有針對當前環(huán)境實現(xiàn),或者如果buf不是java.nio.ByteBuffer類型的對象返回-1。
jlong GetDirectBufferCapacity(jobject buf);
1. Jni中調(diào)用
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是結(jié)構(gòu)體pImageData中的byte[];
希望本文所述對大家的Android程序設(shè)計有所幫助。
相關(guān)文章
android中Bitmap用法(顯示,保存,縮放,旋轉(zhuǎn))實例分析
這篇文章主要介紹了android中Bitmap用法,以實例形式較為詳細的分析了android中Bitmap操作圖片的顯示、保存、縮放、旋轉(zhuǎn)等相關(guān)技巧,需要的朋友可以參考下2015-09-09
Android實現(xiàn)側(cè)滑菜單DrawerLayout
這篇文章主要為大家詳細介紹了Android實現(xiàn)側(cè)滑菜單DrawerLayout,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-05-05
Android網(wǎng)絡(luò)編程之簡易新聞客戶端
這篇文章主要為大家詳細介紹了Android網(wǎng)絡(luò)編程之簡易新聞客戶端的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
完美解決Android Studio集成crashlytics后無法編譯的問題
下面小編就為大家?guī)硪黄昝澜鉀QAndroid Studio集成crashlytics后無法編譯的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05
Android控件PullRefreshViewGroup實現(xiàn)下拉刷新和上拉加載
這篇文章主要為大家詳細介紹了Android控件PullRefreshViewGroup實現(xiàn)下拉刷新和上拉加載效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
AFURLSessionManager 上傳下載使用代碼說明
本文通過代碼給大家介紹了AFURLSessionManager 上傳下載使用說明,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-09-09

