2

Android SDK レベルと Android NDK レベルの間でバイト バッファーを送信するプロジェクトに取り組んでいます。

推奨される方法は、allocateDirect() メソッドを使用して ByteBuffer を使用することです。つまり、SDK レベルでは次のようにします。

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

私の ICS 電話ではすべてが完璧に機能しましたが、友人の Android 2.3.3 バージョンではコードがクラッシュしました。

調査の結果、バージョン 2.3.3 の電話で UnsupportedOperationException をスローしたのは ByteBuffer の array() メソッドであることが判明しました。

どうやら、このメソッドは 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以降で追加のコピーを回避するためのよりスマートな方法はありますか?

4

1 に答える 1

0

Dalvik 実装の変更点は、ダイレクト バイト バッファーが ICS の前に配列によってサポートされていなかったことです。将来のバージョンで array() を呼び出せるという保証はありません。を使用する前に、いつでもhasArray()ByteBufferを確認できます。配列を直接使用できない場合でも、ICS 用にコーディングした方法で、いつでもバッチput()メソッドを使用できます。ループで呼び出す必要はありません。

結論として、Android JNI のヒント ページから引用させてください。VM でバイト バッファーへの直接アクセスがどのように実装されているかによっては、Java で記述されたコードからのデータへのアクセスが非常に遅くなる可能性があります。

于 2012-08-15T10:17:18.353 に答える