Ich habe einen Arbeitsthread im Hintergrund, der Nachrichten verarbeitet. Etwas wie das:
class Worker extends Thread {
public volatile Handler handler; // actually private, of course
public void run() {
Looper.prepare();
mHandler = new Handler() { // the Handler hooks up to the current Thread
public boolean handleMessage(Message msg) {
// ...
}
};
Looper.loop();
}
}
Vom Haupt-Thread (UI-Thread, nicht dass es darauf ankommt) möchte ich so etwas machen:
Worker worker = new Worker();
worker.start();
worker.handler.sendMessage(...);
Das Problem ist, dass ich mich auf eine schöne Rennbedingung vorbereite: Zum Zeitpunkt des worker.handler
Lesens kann nicht sichergestellt werden, dass der Worker-Thread diesem Feld bereits zugewiesen wurde!
Ich kann das nicht einfach Handler
aus dem Worker
Konstruktor des erstellen , da der Konstruktor auf dem Hauptthread ausgeführt wird, sodass sich der Konstruktor Handler
dem falschen Thread zuordnet.
Dies scheint kaum ein ungewöhnliches Szenario zu sein. Ich kann mir mehrere Problemumgehungen einfallen lassen, die alle hässlich sind:
Etwas wie das:
class Worker extends Thread { public volatile Handler handler; // actually private, of course public void run() { Looper.prepare(); mHandler = new Handler() { // the Handler hooks up to the current Thread public boolean handleMessage(Message msg) { // ... } }; notifyAll(); // <- ADDED Looper.loop(); } }
Und aus dem Hauptthema:
Worker worker = new Worker(); worker.start(); worker.wait(); // <- ADDED worker.handler.sendMessage(...);
Aber das ist auch nicht zuverlässig: Wenn das
notifyAll()
vor dem passiertwait()
, werden wir nie geweckt!Übergeben einer Initiale
Message
an denWorker
Konstruktor des Konstruktors, damit dierun()
Methode sie veröffentlicht. Eine Ad-hoc-Lösung funktioniert nicht für mehrere Nachrichten oder wenn wir sie nicht sofort, sondern kurz danach senden möchten.Beschäftigt warten, bis das
handler
Feld nicht mehr istnull
. Ja, ein letzter Ausweg ...
Ich möchte ein Handler
und MessageQueue
im Namen des Worker
Threads erstellen , aber dies scheint nicht möglich zu sein. Was ist der eleganteste Ausweg?
HandlerThread
?