2

ジンジャーブレッドを使用しています。既にネイティブ シリアル ポート (USB ダングルではなく、RS-232 ネイティブ UART) と通信しています。これは、java.io と C で記述された小さなネイティブ コードによって行われ、ストリームの開閉とボーレートの設定を行います。それは機能しますが、最初に考えたのは、入力ストリームを常にポーリングしてシリアルポートからのバイトがあるかどうかを確認するスレッドをセットアップする必要があるため、効率的ではないということでした。CPUやバッテリーの無駄遣い。

    private InputStream mInputStream;
private ReadThread mReadThread;

private class ReadThread extends Thread {

    @Override
    public void run() {
        super.run();
        while(!isInterrupted()) {
            int size;
            try {
                byte[] buffer = new byte[64];
                if (mInputStream == null) return;
                size = mInputStream.read(buffer);
                if (size > 0) {
                    onDataReceived(buffer, size);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }
    }
}

私がする必要があると思ったのは、Android の他のイベントと同じ種類のシグナルを用意することです。そこでは、何らかの種類のリスナーをセットアップして、いくつかのバイトが来ることを通知され、処理するスレッドをウェイクアップできるようにすることができます着信データ。API でそのようなものは見つかりませんでした。

でも、いろいろ調べて、無駄ではないと思うのですが、Androidのスレッドの仕組みに詳しい方からのご意見をいただきたいです。コード行を見てみましょう。

size = mInputStream.read(buffer);

実際にはブロッキング読み取りです。デバイスがどのように開かれたかを調べました。NDK/JNI インターフェイスを介して C で行われ、フラグ「NOBLOCK/NODELAY」なしで開かれています。そのため、while ループで常にスピンするのではなく、mInputStream.read でブロックされ、カーネルは読み取り可能なデータが得られるまで別のスレッドに切り替える必要があります。そのような場合、このコードはまったく問題ありません。この仮定は本当ですか?

私の組み込みシステムの主な目的はほとんどの場合ビデオを表示することであり、舞台裏で管理しているものに多くのリソースを吸い上げてビデオの再生に問題を与えたくないので、それを知りたいです。

4

2 に答える 2

2

アプリケーションを作成してテストした後、質問で行われた最後の仮定は実際には正しいと言えます。デバイスが "NOBLOCK/NODELAY" フラグなしで開いている場合、スレッドは mInputStream.read() でデータが利用可能になるまで中断されます。無駄なポーリングはありません。

于 2012-11-16T21:03:18.463 に答える
0

java.nioパッケージのselector()を使用できます。

http://developer.android.com/reference/java/nio/channels/Selector.html

http://www.drdobbs.com/jvm/high-performance-io-with-java-nio/184406242も参照してください

于 2012-10-16T03:40:36.830 に答える