2011-01-10 12 views
2

HandlersがAndroid/DalvikVMでどのように処理されているのでしょうか。 Android用のアプリケーションを作成しています。あるクラスでは、別のクラスのメッセージを受け取るHandlerメソッドがあります。ハンドラメソッドはスレッドとして動作し、同じクラスのrun()メソッドと非同期であるか、run()メソッドのコード行が終了するまで待つか(アトミック操作の一種)?または、他の何か?Android/DalvikVMはどのようにハンドラを処理しますか?

Handlerメソッドのキューにメッセージを追加し、run()メソッド(producer-consumer)でメッセージを処理して削除したいと思っています。

私のコードの構造:

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

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

あなたの計画が単一の消費者だけを持つことになっているなら、ハンドラは良い選択です。消費者(ハンドラ)からメッセージを削除する必要はなく、処理のために単にhandleMessageに到着します。もしあなたがANRを避けるためにバックグラウンドで処理したいのであれば、あなたはおそらくHandlerThreadを使いたいと思うでしょう。ここではそれ自身のバックグラウンドスレッドで実行されているハンドラの例です。

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

クラス以上の説明では、コードが何であるかのスレッドに無関係である、すべてのクラスが、コードが構成されている方法なので、遊びに来ていないことに注意してください〜で実行される。

関連する問題