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

后端 未结 4 1728
离开以前
离开以前 2020-11-30 17:47

I have a worker thread that sits in the background, processing messages. Something like this:

class Worker extends Thread {

    public volatile Handler hand         


        
4条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-30 17:52

    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(); // <- ADDED
    worker.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!

提交回复
热议问题