Android在JNI中使用ByteBuffer的方法
本文實(shí)例講述了Android在JNI中使用ByteBuffer的方法。分享給大家供大家參考。具體如下:
一、ByteBuffer 定義
在NIO中,數(shù)據(jù)的讀寫操作始終是與緩沖區(qū)相關(guān)聯(lián)的(讀取時(shí)信道(SocketChannel)將數(shù)據(jù)讀入緩沖區(qū),寫入時(shí)首先要將發(fā)送的數(shù)據(jù)按順序填入緩沖區(qū))
緩沖區(qū)是定長的,基本上它只是一個(gè)列表,它的所有元素都是基本數(shù)據(jù)類型。ByteBuffer是最常用的緩沖區(qū),它提供了讀寫其他數(shù)據(jù)類型的方法,且信道的讀寫方法只接收ByteBuffer。
ByteBuffer有以下幾種常見屬性:
mark:初始值為-1,標(biāo)記索引地點(diǎn);
position:初始值為0,索引下標(biāo);
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表示一個(gè)數(shù)組
2. 回繞緩沖區(qū)
buf.flip();
這個(gè)方法用來將緩沖區(qū)準(zhǔn)備為數(shù)據(jù)傳出狀態(tài),執(zhí)行以上方法后,輸出通道會從數(shù)據(jù)的開頭而不是末尾開始.回繞保持緩沖區(qū)中的數(shù)據(jù)不變,只是準(zhǔn)備寫入而不是讀取。
3. 清除緩沖區(qū)
buf.clear();
這個(gè)方法實(shí)際上也不會改變緩沖區(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有三個(gè)函數(shù)可以用于NIO的直接緩沖器。一個(gè)直接字節(jié)緩沖器是一個(gè)用于字節(jié)數(shù)據(jù)的容器,Java將盡力在它上面執(zhí)行本機(jī)I/O操作。JNI定義了三個(gè)用于NIO操作的函數(shù)。
基于到存儲器地址的指針以及存儲器長度(容量),函數(shù)分配并且返回一個(gè)新的Java.nio.ByteBuffer。如果函數(shù)沒有針對當(dāng)前Java虛擬機(jī)實(shí)現(xiàn),則返回NULL,或者拋出一個(gè)異常。如果沒有存儲器可用,則將會拋出一個(gè)OutOfMemoryException。
jobject NewDirectByteBuffer(void* address, jlong capacity);
GetDirectBufferAddress函數(shù)返回一個(gè)指向被傳入的java.nio.ByteBuffer對象的地址指針。如果函數(shù)尚未針對當(dāng)前虛擬機(jī)實(shí)現(xiàn),或者如果buf不是java.nio.ByteBuffer的一個(gè)對象,又或者存儲器區(qū)尚未定義,則都將返回NULL。
void* GetDirectBufferAddress(jobject buf);
GetDirectBufferCapacity函數(shù)返回被傳入的java.nio.ByteBuffer對象的容量(以字節(jié)計(jì)數(shù))。如果函數(shù)沒有針對當(dāng)前環(huán)境實(shí)現(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è)計(jì)有所幫助。
相關(guān)文章
Android仿滴滴出行驗(yàn)證碼輸入框功能實(shí)例代碼
最近項(xiàng)目經(jīng)理交給我們組一個(gè)類似滴滴出行填寫驗(yàn)證碼的彈框功能,拿到這個(gè)項(xiàng)目需求真是把我忙暈了,下面通過本文給大家分享Android仿滴滴出行驗(yàn)證碼輸入框功能實(shí)例代碼,需要的朋友參考下吧2017-12-12Android垃圾回收機(jī)制及程序優(yōu)化System.gc
這篇文章主要介紹了Android垃圾回收機(jī)制及程序優(yōu)化System.gc的相關(guān)資料,需要的朋友可以參考下2016-01-01Android 實(shí)現(xiàn)單線程輪循機(jī)制批量下載圖片
這篇文章主要介紹了Android 單線程輪循機(jī)制批量下載圖片的相關(guān)資料,這里對實(shí)現(xiàn)步驟做了詳細(xì)介紹,需要的朋友可以參考下2017-07-07Android自定義控件之可拖動控制的圓環(huán)控制條實(shí)例代碼
這篇文章主要介紹了Android自定義控件之可拖動控制的圓環(huán)控制條實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04Android開發(fā)中ImageLoder加載網(wǎng)絡(luò)圖片時(shí)將圖片設(shè)置為ImageView背景的方法
這篇文章主要介紹了Android開發(fā)中ImageLoder加載網(wǎng)絡(luò)圖片時(shí)將圖片設(shè)置為ImageView背景的方法,涉及Android ImageView圖片加載及背景設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2018-01-01