Tengo un hilo de trabajo que se encuentra en segundo plano, procesando mensajes. Algo como esto:
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();
}
}
Desde el hilo principal (hilo de la interfaz de usuario, no es que importe) me gustaría hacer algo como esto:
Worker worker = new Worker();
worker.start();
worker.handler.sendMessage(...);
El problema es que esto me prepara para una hermosa condición de carrera: en el momento en que worker.handler
se lee, ¡no hay forma de estar seguro de que el hilo de trabajo ya se haya asignado a este campo!
No puedo simplemente crear el Handler
desde el Worker
constructor de, porque el constructor se ejecuta en el hilo principal, por lo que Handler
se asociará con el hilo incorrecto.
Esto no parece un escenario poco común. Puedo encontrar varias soluciones, todas feas:
Algo como esto:
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(); } }
Y del hilo principal:
Worker worker = new Worker(); worker.start(); worker.wait(); // <- ADDED worker.handler.sendMessage(...);
Pero esto tampoco es confiable: si
notifyAll()
sucede antes delwait()
, ¡nunca nos despertaremos!Pasando una inicial
Message
alWorker
constructor de, haciendo que elrun()
método la publique. Una solución ad-hoc, no funcionará para varios mensajes, o si no queremos enviarla de inmediato, pero poco después.Ocupado esperando hasta que el
handler
campo ya no esténull
. Sí, un último recurso ...
Me gustaría crear un Handler
y MessageQueue
en nombre del Worker
hilo, pero esto no parece ser posible. ¿Cuál es la forma más elegante de salir de esto?
HandlerThread
?