Honeycomb 下的 Android 不支持 Bytebuffer array() 方法

Posted

技术标签:

【中文标题】Honeycomb 下的 Android 不支持 Bytebuffer array() 方法【英文标题】:Bytebuffer array() method not supported in Android below Honeycomb 【发布时间】:2012-05-22 10:49:20 【问题描述】:

我正在做一个项目,我想在 android SDK 级别和 Android NDK 级别之间发送一个字节缓冲区。

推荐的方法似乎是通过 allocateDirect() 方法使用 ByteBuffer,即在 SDK 级别上做:

ByteBuffer frameBuf = ByteBuffer.allocateDirect( 10000 );
int frameSize = fillMyArrayMethod(frameBuf.array());
UseArrayInNdk(frameBuf);

在我的 ICS 手机上一切正常,但在我朋友的 Android 2.3.3 版本上,代码崩溃了。

调查发现是ByteBuffer的array()方法在2.3.3版本的手机上抛出了UnsupportedOperationException。

显然Honeycomb以下的Android版本不支持此方法。

因此,由于我无法获得指向缓冲区的数组指针,我现在不得不在我的 NDK 中使用之前为数组中的所有数据创建一个额外的 put(),即像这样:

ByteBuffer frameBuf = ByteBuffer.allocateDirect( 10000 );
Byte[] tmpBuf = new byte[10000];
int frameSize = fillMyArrayMethod(tmpBuf);

for (int i=0; i<frameSize; i++)

    frameBuf.put(i, tmpBuf[i]);

UseArrayInNdk(frameBuf);

好吧,在 Android Honeycomb 及以上代码上执行此操作没问题,但在 2.3.3 及以下版本是否有更智能的方法来避免额外的复制?

【问题讨论】:

【参考方案1】:

Dalvik 实现的变化是直接字节缓冲区在 ICS 之前没有由数组支持。不能保证在以后的版本中可以调用 array()。在使用ByteBuffer 之前,您始终可以检查hasArray()。即使您不能直接使用数组,也可以像为 ICS 编码的方式一样,始终使用批处理 put() 方法,无需循环调用。

最后,让我引用 Android JNI 提示页面:Depending on how direct byte buffer access is implemented in the VM, accessing the data from code written in Java can be very slow.

【讨论】:

以上是关于Honeycomb 下的 Android 不支持 Bytebuffer array() 方法的主要内容,如果未能解决你的问题,请参考以下文章

Android Honeycomb:如何更改 FrameLayout 中的片段,而不重新创建它们?

Android:BitmapFactory.nativeDecodeAsset 处的 OutOfMemoryError(Honeycomb 3.0 及更高版本)

Android 支持库如何工作?

ActionBar pre Honeycomb

Android Honeycomb 中的加载程序

如何获取 android Honeycomb 系统的屏幕宽度和高度?