2

Android/DalvikVM でハンドラーがどのように処理されるのか疑問に思っています。私は Android 用のアプリケーションを作成しています。あるクラスには、別のクラスからメッセージを受け取る Handler メソッドがあります。Handler メソッドは Thread として機能し、同じクラスの run() メソッドに対して非同期になりますか、それとも run() メソッドのコード行が完了するまで待機しますか (一種のアトミック操作)? または、他の何か?

Handler メソッドでメッセージをキューに追加し、run() メソッド (プロデューサー-コンシューマー) でメッセージを処理および削除したいので、疑問に思っています。

私のコード構造:

public class Parser implements Runnable {
    public void run() {
            while(true) {
            // Remove a byte from the ring buffer and parse it
            byte b = Ringbuffer_read();
            // Parse
        try {
                Thread.sleep(40);
            } catch (InterruptedException e) {}
           }
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MESSAGE_READ:
                // Store all the received bytes in the ring buffer
                for (int i = 0; i < msg.arg1; i++) {
                    Ringbuffer_store(((byte[]) msg.obj)[i]);
                }
                break;
            }
        }
    };
}

ハンドラーのコードはいつ実行されますか? run() メソッドのコードはどこかで中断されますか? バッファが破損しないように、run() およびハンドラ メソッドのコードの周りに、同期やセマフォなどを用意する必要がありますか?

4

1 に答える 1

4

AndroidHandlerは、作成されたスレッドに自分自身を関連付けます(スレッドにすでにルーパーがあると仮定します)。デフォルトでは、Androidのコールバックは、UIスレッドとも呼ばれる「main」という名前のスレッドで実行されます。postメソッドが呼び出されるスレッドに関係なく、メソッドはhandleMessageハンドラーが作成されたスレッド(通常は「メイン」スレッド)から呼び出されます。handleMessageメソッドは常に同じスレッドで呼び出されるため、一度に処理されるメッセージは1つだけです。

コンシューマーを1つだけにする計画の場合は、ハンドラーが適しています。コンシューマー(ハンドラー)からメッセージを削除する必要はありません。代わりに、メッセージはhandleMessage処理のために到着するだけです。「メイン」スレッドで処理を実行する場合は、新しいハンドラーを作成するだけです。ANRを回避するためにバックグラウンドで処理を実行する場合は、HandlerThreadを使用することをお勧めします。独自のバックグラウンドスレッドで実行されているハンドラーの例を次に示します。

HandlerThread handlerThread = new HandlerThread("Consumer");
handlerThread.start();
Handler consumer = new Handler(handlerThread.getLooper()) {
    public void handleMessage (Message msg) {
    }
};

上記の説明では、クラスはコードの構造であり、コードが実行されるスレッドとは無関係であるため、クラスはまったく機能しないことに注意してください。

于 2011-01-10T23:59:23.750 に答える