How to create a Looper thread, then send it a message immediately? How to create a Looper thread, then send it a message immediately? multithreading multithreading

How to create a Looper thread, then send it a message immediately?


Eventual solution (minus error checking), thanks to CommonsWare:

class Worker extends HandlerThread {    // ...    public synchronized void waitUntilReady() {        d_handler = new Handler(getLooper(), d_messageHandler);    }}

And from the main thread:

Worker worker = new Worker();worker.start();worker.waitUntilReady(); // <- ADDEDworker.handler.sendMessage(...);

This works thanks to the semantics of HandlerThread.getLooper() which blocks until the looper has been initialized.


Incidentally, this is similar to my solution #1 above, since the HandlerThread is implemented roughly as follows (gotta love open source):

public void run() {    Looper.prepare();    synchronized (this) {        mLooper = Looper.myLooper();        notifyAll();    }    Looper.loop();}public Looper getLooper() {    synchronized (this) {        while (mLooper == null) {            try {                wait();            } catch (InterruptedException e) {            }        }    }    return mLooper;}

The key difference is that it doesn't check whether the worker thread is running, but that it has actually created a looper; and the way to do so is to store the looper in a private field. Nice!


take a look at the source code of HandlerThread

@Override     public void run() {         mTid = Process.myTid();         Looper.prepare();         synchronized (this) {             mLooper = Looper.myLooper();             notifyAll();         }         Process.setThreadPriority(mPriority);         onLooperPrepared();         Looper.loop();         mTid = -1;     }

Basically, if you are extending Thread in worker and implementing your own Looper, then your main thread class should extend worker and set your handler there.


This is my solutions: MainActivity:

//Other Code mCountDownLatch = new CountDownLatch(1);        mainApp = this;        WorkerThread workerThread = new WorkerThread(mCountDownLatch);        workerThread.start();        try {            mCountDownLatch.await();            Log.i("MsgToWorkerThread", "Worker Thread is up and running. We can send message to it now...");        } catch (InterruptedException e) {            e.printStackTrace();        }        Toast.makeText(this, "Trial run...", Toast.LENGTH_LONG).show();        Message msg = workerThread.workerThreadHandler.obtainMessage();        workerThread.workerThreadHandler.sendMessage(msg);

The WorkerThread Class:

public class WorkerThread extends Thread{    public Handler workerThreadHandler;    CountDownLatch mLatch;    public WorkerThread(CountDownLatch latch){        mLatch = latch;    }    public void run() {        Looper.prepare();        workerThreadHandler = new Handler() {            @Override            public void handleMessage(Message msg) {                Log.i("MsgToWorkerThread", "Message received from UI thread...");                        MainActivity.getMainApp().runOnUiThread(new Runnable() {                            @Override                            public void run() {                                Toast.makeText(MainActivity.getMainApp().getApplicationContext(), "Message received in worker thread from UI thread", Toast.LENGTH_LONG).show();                                //Log.i("MsgToWorkerThread", "Message received from UI thread...");                            }                        });            }        };        Log.i("MsgToWorkerThread", "Worker thread ready...");        mLatch.countDown();        Looper.loop();    }}