Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if a Handler posts a message to a thread after Looper.prepare() but before Looper.loop() has been called?

Tags:

android

looper

Consider the following snippet:

Looper.prepare();
handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            getLooper().quitSafely();
        }
    };
for(int i = 0; i < urls.size(); i++) {
    useCaseProvider.get().execute(callback, handler, urls.get(i), threadPool);
}
Looper.loop();

//Continue processing the results of all the use cases after the    
//loop has been asked to terminated via the handler

A little background: I'm doing some processing on the UI thread where I will need to ping a large about of devices and do something with the result. I need to perform the requests in parallel to be efficient.

Question: If one of these use cases somehow executed fast enough and made a callback before I was able to hit Looper.loop(); would the message be queued or just lost? Callbacks are being posted back to this thread by the handler posting a runnable to the original thread.

like image 911
Chad Avatar asked Mar 06 '15 22:03

Chad


People also ask

What kind of method prepare () is of Looper class?

Creating Looper and MessageQueue for a Thread: prepare() identifies the calling thread, creates a Looper and MessageQueue object and associate the thread with them in ThreadLocal storage class. Looper. loop() must be called to start the associated looper.

What does Looper prepare do?

prepare. Initialize the current thread as a looper. This gives you a chance to create handlers that then reference this looper, before actually starting the loop. Be sure to call loop() after calling this method, and end it by calling quit() .

What is the purpose of post () method related to a handler?

post. Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.

What is the difference between handler and looper?

Looper is an abstraction over event loop (infinite loop which drains queue with events) and Handler is an abstraction to put/remove events into/from queue with events (which is drained by Looper) and handle these events when they are processed.


1 Answers

Assuming you have invoked Looper.prepare() prior to your useCaseProvider delivering results, you should be fine. If Looper.prepare was not called you should be seeing RuntimeException being thrown.

The Looper object is tied to a thread local which hosts the message queue. The Looper.prepare function will construct this message queue at which point you can begin queuing up messages. Once you fire Looper.loop() that's when those pending messages will begin to execute.

Looking at the snippet, I'm not too sure how things are tied together. Generally you want to construct a looper like this:

private static final class MyThread extends Thread {
    private Handler mHandler;

    @Override
    public void run() {
        Looper.prepare();

        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // handle message
            }
        };

        Looper.loop();
    }

    public Handler getHandler() {
        return mHandler;
    }
}

I'm assuming your thread pool is then a pool of MyThread threads, each of which have their own Looper. The thread pool should initialize your threads so once you deliver a Runnable to be executed by your thread, the run() method should have the Looper initialized.

On the other hand, if you wish to associate your Handler with a particular looper (ie. you are not constructing the Handler within a thread like above) then you should be passing the Looper thread in to the constructor like:

Handler h = new Handler(myLooperThread);

If you don't specify that, then the handler uses the thread in which it was created to grab that thread's Looper from the ThreadLocal object.

Lastly if your intentions are to have messages delivered on the Handler which is associated with the UI thread then you should not be concerned about calling Looper.prepare or Looper.loop. This is handled by the Activity.

like image 175
jagsaund Avatar answered Oct 03 '22 00:10

jagsaund