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

I checked the official Android documentation / guide for Looper , Handler and MessageQueue . But I could not understand it. I am new to android and am very confused by these concepts.

+90
android handler looper message-queue
Oct 13 '12 at 23:29
source share
5 answers

Looper is a message processing loop: it reads and processes elements from a MessageQueue . The Looper class is commonly used with HandlerThread (a subclass of Thread ).

Handler is a utility class that facilitates interacting with Looper primarily by publishing messages and Runnable objects in a MessageQueue stream. When a Handler is created, it binds to a specific Looper (and its associated thread and message queue).

In normal use, create and start HandlerThread , and then create a Handler object (or objects) with which other threads can interact with the HandlerThread instance. Handler must be created while running on HandlerThread , although after creating it there are no restrictions on which threads can use Handler scheduling methods ( post(Runnable) , etc.)

The main thread (aka the user interface thread) in the Android application is configured as a handler thread before creating the application instance.

Besides the documentation class, there is a good discussion about it all here .

PS All the classes mentioned above are in the android.os package.

+101
Oct 13
source share
— -

It is well known that it is illegal to update user interface components directly from threads other than the main thread in android. This android document ( Handling Costly Operations in a UI Thread) suggests the following steps if we need to start a separate thread in order to do some expensive work and update the interface after it is completed. The idea is to create a Handler object associated with the main thread , and submit the Runnable at the appropriate time. This Runnable will be called in the main thread . This mechanism is implemented using the Looper and Handler classes.

The Looper class supports MessageQueue , which contains a list of messages . An important character of Looper is that it is associated with the stream in which Looper is created . This connection is stored forever and cannot be broken or altered. Also note that a thread cannot be associated with more than one Looper . To guarantee this association, Looper is stored in streaming local storage and cannot be created directly through its constructor. The only way to create it is to invoke the prepare static method on Looper . the preparation method first examines the ThreadLocal of the current thread to ensure that the Looper is not associated with the thread. After the exam, a new Looper is created and saved in ThreadLocal . Looper prepared Looper , we can call the loop method to check for new messages and have a Handler to solve these problems.

As the name implies, the Handler class is mainly responsible for processing (adding, deleting, dispatching) messages in the current MessageQueue stream. A Handler instance is also associated with a stream. the binding between the handler and the thread is achieved using Looper and MessageQueue . A Handler always bound to a Looper , and then bound to a thread associated with , with Looper . Unlike Looper , multiple instances of Handler can be bound to the same thread. Whenever we call post or any methods like Handler , a new message is added to the associated MessageQueue . The target message field is assigned the current Handler instance. When Looper receives this message, it calls dispatchMessage in the message's destination field so that the message returns to the Handler instance to be processed, but on the correct thread. The relationships between Looper , Handler and MessageQueue are shown below:

enter image description here

+91
Oct 13 '12 at 23:55
source share

Let's get started with Looper. You can more easily understand the relationship between Looper, Handler, and MessageQueue when you understand what Looper is. You can also better understand what Looper is in the context of a graphical interface. Looper is made to do 2 things.

1) Looper converts a regular thread that terminates when its run() method returns, into something that runs continuously until the Android application starts , which is necessary in the GUI environment (Technically, it still terminates when the run() method returns run() . But let me explain what I mean below).

2) Looper provides a queue in which jobs are performed that are also needed in the GUI environment.

As you may know, when the application starts, the system creates a thread for the application called the "main", and Android applications usually start completely in one thread by default, the "main thread". But the main thread is not some secret, special thread . This is just a regular thread, which you can also create with new Thread() code new Thread() , which means that it exits when its run() method returns! Think of the example below.

 public class HelloRunnable implements Runnable { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new Thread(new HelloRunnable())).start(); } } 

Now let's apply this simple principle to an Android application. What happens if the Android application is launched in a normal thread? A thread with the name "main" or "UI" or something else launches the application and draws the entire interface. So, the first screen is displayed for users. And now what? Does the main thread end? No, it should not. You should wait for users to do something, right? But how can we achieve this behavior? Well, we can try with Object.wait() or Thread.sleep() . For example, the main thread completes its initial work to display the first screen and sleeps. He wakes up, which means interruption when a new job is selected. So far so good, but at the moment we need a data structure, similar to a queue, for storing several tasks. Think about when the user touches the screen sequentially and the task takes longer to complete. So, we need a data structure for storing tasks that must be executed in the first-come-first-go order. In addition, you can imagine that it is not easy to implement a constantly working thread and a job-task upon receipt using an interrupt, and this leads to complex and often unsupported code. We would rather create a new mechanism for this purpose, and that's what Looper is all about . The official document of the Looper class states: "A message loop is not associated with threads by default," and Looper is the class "used to start a message loop for a stream." Now you can understand what this means.

Let's move on to Handler and MessageQueue. Firstly, MessageQueue is the queue I mentioned above. He is inside the Looper, and that's him. You can verify this using the source code of the Looper class . The Looper class has a MessageQueue member variable.

Then what is a handler? If there is a queue, then there must be a method that allows us to queue a new task, right? This is what Handler does. We can queue a new task (MessageQueue) using various post(Runnable r) methods post(Runnable r) . It. It is all about Looper, Handler and MessageQueue.

My last word, so basically Looper is a class created to solve a problem that occurs in a GUI environment. But this kind of need may arise in other situations. This is actually a fairly well-known template for a multi-threaded application, and you can learn more about it in Doug Lee's “Parallel Programming in Java” (it would be especially useful, chapter 4.1.4 “Workflows”). In addition, you can imagine that this type of mechanism is not unique to the Android platform, but all graphical interfaces may need some similarities with this. You can find almost the same mechanism in the Java Swing Framework.

+69
Dec 30 '15 at 7:02
source share

MessageQueue : This is a low-level class containing a list of messages sent using Looper . Messages are not added directly to the MessageQueue , but rather through the Handler objects associated with the Looper . [ 3 ]

Looper : It moves around the MessageQueue that contains the sent messages. The actual queue management task is performed by the Handler , which is responsible for processing (adding, deleting, scheduling) messages in the message queue. [ 2 ]

Handler : it allows you to send and process Message and Runnable objects associated with the MessageQueue stream. Each Handler instance is associated with one thread and this thread's message queue. [ 4 ]

When you create a new Handler , it is attached to the thread / message queue of the thread that creates it - from this point it will deliver messages and runnables to the message queue and execute them when the message queue exits .

Please see the image below [ 2 ] for a better understanding.

enter image description here

+25
May 01 '16 at 13:16
source share

MessageQueue, Handler, Looper in Android MessageQueue:

MessageQueue is a message loop or message queue that basically contains a list of messages or Runnables (a set of executable code).

In other words, MessageQueue is a queue that has tasks called messages that need to be processed.

Note. Android supports MessageQueue in the main thread.

Looper:

Looper is the worker that serves the MessageQueue for the current thread. Looper goes through the message queue and sends messages to the appropriate handlers for processing.

Any thread can have only one unique Looper, this limitation is achieved using the ThreadLocal storage concept.

Benefits of Looper and MessageQueue

There are some advantages to using Looper and MessageQueue, as described below-

· Using MessageQueue, execution is sequential, so in the case of parallel threads this will avoid race conditions.

· Normally, a stream cannot be reused after it has completed its work. But the stream with Looper persists until you call the quit method, so you don’t need to create a new instance every time you want to run the task in the background.

Handler:

A handler allows you to connect to a user interface thread from another background thread. This is useful in Android, since Android does not allow other threads to interact directly with the user interface thread.

The handler allows you to send and process Message and Runnable objects associated with MessageQueue threads. Each handler instance is associated with one thread and with this thread message queue.

When you create a new handler, it binds to the thread / message queue of the thread that creates it - from now on, it will deliver messages and executable files to this message queue and execute them as they exit the message queue.,

There are two main uses for the handler:

(1) To schedule the execution of messages and executables in the future. In other words, perform actions in the same thread in the future.

(2) queuing up an action to be performed on a thread other than your own. In other words, queue an action to execute on another thread.

+3
Apr 07 '18 at 10:01
source share



All Articles