2011-01-10 12 views
2

Ich frage mich, wie Handler in Android/DalvikVM verarbeitet werden. Ich schreibe eine Anwendung für Android, und in einer Klasse habe ich eine Handler-Methode, die Nachrichten von einer anderen Klasse empfängt. Funktioniert die Handler-Methode als Thread und ist asynchron zur run() - Methode in derselben Klasse oder wartet sie, bis eine Codezeile in der run() -Methode beendet ist (eine Art atomarer Vorgang)? Oder etwas anderes?Wie verarbeitet Android/DalvikVM Handler?

Ich frage mich, weil ich Nachrichten zu einer Warteschlange in der Handler-Methode hinzufügen und sie in der run() -Methode (Producer-Consumer) verarbeiten und entfernen möchte.

Meine Code-Struktur:

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; 
      } 
     } 
    }; 
} 

Wann wird in der Prozedur der Code ausgeführt? Wird der Code in der run() -Methode zu irgendeinem Zeitpunkt unterbrochen? Muss ich in der run() - und handler-Methode eine Synchronisation oder Semaphore oder etwas um den Code herum haben, damit ich meinen Puffer nicht beschädige?

Antwort

4

Ein Android Handler verbindet sich mit dem Thread, in dem es erstellt wird (vorausgesetzt, der Thread hat bereits einen Looper). Standardmäßig werden Android-Callbacks auf einem Thread namens "main" ausgeführt, der auch als ui-Thread bezeichnet wird. Unabhängig davon, welchen Thread die post-Methode von der handleMessage-Methode aufgerufen wird, wird von dem Thread aufgerufen, in dem der Handler erstellt wurde (normalerweise der "Haupt" -Thread). Da die Methode handleMessage immer im selben Thread aufgerufen wird, wird jeweils nur eine Nachricht verarbeitet.

Wenn Ihr Plan nur einen einzigen Verbraucher haben soll, dann ist Handler eine gute Wahl. Sie müssen keine Nachrichten von Ihrem Consumer (dem Handler) entfernen, stattdessen werden sie einfach zur Verarbeitung in handleMessage ankommen. Wenn Sie die Verarbeitung für den Hauptthread durchführen möchten, müssen Sie nur einen neuen Handler erstellen. Wenn Sie die Verarbeitung im Hintergrund durchführen möchten, um ANRs zu vermeiden, sollten Sie wahrscheinlich HandlerThread verwenden. Hier ist ein Beispiel für einen Handler auf seinen eigenen Hintergrund-Thread ausgeführt wird:

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

Beachten Sie, dass in der obigen Beschreibung Klasse nicht ins Spiel kommt überhaupt, weil Klassen sind wie Code strukturiert ist, was in keinem Zusammenhang ist das, was fädelt der Code ausgeführt auf.