Looper

Looper is used to loop messages from a message queue and process them via Handler’s dispatchMessage() method.

Initialize the stars

In general, objects are initialized through constructors

Private Looper(Boolean quitAllowed) {// initialize a MessageQueue mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }Copy the code

The constructor is private, so you can’t create a Looper object directly by creating a new externally. By tracking where the constructor was called, you can see that the prepare() method was called.

public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() ! = null) { throw new RuntimeException("Only one Looper may be created per thread"); } // Create a Looper object and bind it to the current thread sthreadLocal. set(new Looper(quitAllowed)); }Copy the code

For null, create a Looper object and store it in sThreadLocal. We will discuss ThreadLocal in the next article

Implementing a thread local storage, what is that? A variable that gives each thread a value. All threads share the same ThreadLocal object, but each thread gets a different value here, and changes made by one thread here do not affect other threads. The value can be NULL.

Here are some common interview questions

  1. How many Looper objects can be in a thread

  2. How many message queues can a Looper object have

Poll message queue loop()

This is nothing to say, directly on the source code, the content of the source code is some long, but after the deletion, the final process is roughly as follows:

Public static void loop() {final Looper me = myLooper(); // If the Looper object is empty, throw an exception. If (me == null) {throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } // Final MessageQueue queue = me.mqueue; // Start an infinite loop for (;;) Message MSG = queue.next(); // might block // If the message is empty, the message queue has exited, If (MSG == null) {// No message indicates that the message queue is formspapers. Return; } // omit some code..... / / to MSG. Target, namely the handler to handle the message MSG. Target. DispatchMessage (MSG); // Discard the message msg.recycleunchecked (); }}Copy the code
  1. First check whether the Looper object is empty, which indicates that it is called in the current threadLooper.loop()Before, must be called firstLooper.prepare()Method to create a Looper object
  2. Start an endless loop and then pass through MessageQueuenext()Method, which you can look at in detail here【Handler Series 2 】 MessageQueue, if the retrieved message is null, it indicates that the current message queue has terminated, and directly exits the infinite loop
  3. Passes the fetched message to MSG. Target’sdispatchMessage()Method can be viewed in detail here【Handler series 3 】 Handler complete parsing, MSG. Target is actually atHandler.obtainMessage()Assigns the current Handler to the message’s
  4. Finally, the message is recycled

conclusion

Looper is extremely simple. It provides an infinite loop, retrieves the message from MessageQuene, passes it to Handler to process the message, and then recycles it.

Although the source is simple, every interview will encounter about Looper interview questions

  1. A thread can have multiple Looper objects, how many message queues, and how many Handler objects
  2. Looper opens an infinite loop in the main thread, why does it not cause a deadlock

Finally, readers are welcome to leave comments to answer these two interview questions!!