2013-03-21 13 views
5

Ich versuche, Handler zu implementieren, die denselben Looper aus verschiedenen Threads abhören.Mit Looper.getMainLooper() initialisierte Handler reagieren nicht auf Nachrichtenrückrufe.

Unten habe ich zwei Handler, eine im Haupt-Thread erstellt, eine andere im Unter-Thread, aber beide sind initialisiert, um auf dem Main Looper zu hören.

Aber wenn ich eine Nachricht wie unten senden, druckt nur der Kindhandler die Nachricht. Der Haupt-Handler empfängt die Nachricht nicht.

03-20 22:02:26.754: A/(12857): send msg to main looper 
03-20 22:02:26.847: A/(12857): child:{ what=100 when=-8ms } 

Was mache ich falsch? Danke fürs Lesen.

Antwort

10

Jede Handler Instanz steuert das Ziel Message und es gibt keine Möglichkeit, sie zu teilen, so dass jede Nachricht oder Post, die an eine Handler gesendet wird, nur von dieser Instanz ausgeführt wird.

Die Looper zeigt an, welcher Thread die Nachrichten/Runnables gesendet wird am ausgeführt werden. In Ihrem Code führen beide Handler handleMessage() im Hauptthread aus, obwohl sie in separaten Threads erstellt wurden. Das ist der eigentliche Grund, warum Sie eine Looper Instanz zu einem Handler passieren können ... wenn Sie nicht Looper passieren, dann die Handler Code auf dem Thread ausgeführt wird, in dem es erstellt wurde (die Muss auch ein Looper Faden sein) .

Darüber hinaus gibt es keinen Grund, mehrere Handler zu erstellen, um Daten auf diese Weise zu veröffentlichen. Eine einzelne Handler ist entworfen, um Nachrichten von mehreren Threads gesendet werden, und sie sind alle in einer MessageQueue serialisiert und auf dem gewählten Looper Thread ausgeführt. Sie können direkt vom Hintergrundthread an mMain senden, um Code für diesen Thread auszuführen. In diesem Fall ist die Übergabe des Looper redundant bei diesem Code bereits auf dem Haupt-Thread.

+0

Ich sehe, danke! Angenommen, eines Tages wäre das Runnable eine äußere Klasse anstelle einer inneren Klasse, ich sollte ihm über seinen Konstruktor einen initialisierten Handler übergeben, richtig? –

+0

Die Architektur wäre anwendungsabhängig, aber Sie benötigen einen Verweis auf den 'Handler' von wo immer Sie Nachrichten veröffentlichen möchten. – Devunwired

+0

Warum nicht einfach einen Handler (this.getMainLooper()) im Anwendungskontext verwenden (die Klasse, die Application erweitert)? Wäre das nicht sauberer als in einer Aktivität? –

1

Nachrichten, die an eine Handler gesendet werden, werden nur von dieser Handler verarbeitet, auch wenn sie eine Looper teilen.

im Quellcode Buried für Handler ist die Linie

msg.target = this; 

Dies keine andere Handler berühren wird es gewährleistet.