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.