Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the relationship between Looper, Handler and MessageQueue in Android?

I have checked the official Android documentation/guide for Looper, Handler and MessageQueue . But I couldn't get it. I am new to android, and got very confused with these concepts.

like image 252
Blake Avatar asked Oct 13 '12 23:10

Blake


People also ask

What is Looper message and handler?

Looper is a worker that keeps a thread alive, loops through MessageQueue and sends messages to the corresponding handler to process. Finally Thread gets terminated by calling Looper's quit() method.

How many loopers and handlers can be attached to a thread?

2. Each thread can have only one Looper. This is controlled by the ThreadLocal<Looper> object inside Looper class. So calling prepare method twice inside same thread will also lead to an exception.

What is the difference between handler and Handlerthread?

The main difference between Handler and Thread is that a handler is a function or a method that is capable of performing a specific task while a thread is a small, lightweight execution unit within a process.

What is the use of Looper in android?

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.


2 Answers

A Looper is a message handling loop: it reads and processes items from a MessageQueue. The Looper class is usually used in conjunction with a HandlerThread (a subclass of Thread).

A Handler is a utility class that facilitates interacting with a Looper—mainly by posting messages and Runnable objects to the thread's MessageQueue. When a Handler is created, it is bound to a specific Looper (and associated thread and message queue).

In typical usage, you create and start a HandlerThread, then create a Handler object (or objects) by which other threads can interact with the HandlerThread instance. The Handler must be created while running on the HandlerThread, although once created there is no restriction on what threads can use the Handler's scheduling methods (post(Runnable), etc.)

The main thread (a.k.a. UI thread) in an Android application is set up as a handler thread before your application instance is created.

Aside from the class docs, there's a nice discussion of all of this here.

P.S. All the classes mentioned above are in the package android.os.

like image 106
Ted Hopp Avatar answered Sep 29 '22 10:09

Ted Hopp


It's widely known that it's illegal to update UI components directly from threads other than main thread in android. This android document (Handling Expensive Operations in the UI Thread) suggests the steps to follow if we need to start a separate thread to do some expensive work and update UI after it's done. The idea is to create a Handler object associated with main thread, and post a Runnable to it at appropriate time. This Runnable will be invoked on the main thread. This mechanism is implemented with Looper and Handler classes.

The Looper class maintains a MessageQueue, which contains a list messages. An important character of Looper is that it's associated with the thread within which the Looper is created. This association is kept forever and can't be broken nor changed. Also note that a thread can't be associated with more than one Looper. In order to guarantee this association, Looper is stored in thread-local storage, and it can't be created via its constructor directly. The only way to create it is to call prepare static method on Looper. prepare method first examines ThreadLocal of current thread to make sure that there isn't already a Looper associated with the thread. After the examination, a new Looper is created and saved in ThreadLocal. Having prepared the Looper, we can call loop method on it to check for new messages and have Handler to deal with them.

As the name indicates, the Handler class is mainly responsible for handling (adding, removing, dispatching) messages of current thread's MessageQueue. A Handler instance is also bound to a thread. The binding between Handler and Thread is achieved via Looper and MessageQueue. A Handler is always bound to a Looper, and subsequently bound to the thread associated with the Looper. Unlike Looper, multiple Handler instances can be bound to the same thread. Whenever we call post or any methods alike on the Handler, a new message is added to the associated MessageQueue. The target field of the message is set to current Handler instance. When the Looper received this message, it invokes dispatchMessage on message's target field, so that the message routes back to to the Handler instance to be handled, but on the correct thread. The relationships between Looper, Handler and MessageQueue is shown below:

enter image description here

like image 40
K_Anas Avatar answered Sep 29 '22 11:09

K_Anas