This is the 18th day of my participation in the August Genwen Challenge.More challenges in August

The handler calls the sendMessage method and finally passes the Message object to Messagequeue.

So how does the message get out of the message queue? Look back to ActiviryThread’s main method for clues. The source code is posted above. We found the penultimate line looper.loop (), which simply means that the message loop performs a loop operation.

There must be something to satisfy our curiosity. So follow up. The loop method is as follows:

public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging ! = null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); if (logging ! = null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent  = Binder.clearCallingIdentity(); if (ident ! = newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycleUnchecked(); }}Copy the code

Just focus on what’s important. The first thing is to call the myLooper method to get the Looper object, that’s fine, so keep going

MessageQueue queue = me.mQueue
Copy the code

The associated messagequeue is then fetched from the Looper object, followed by an endless loop where messagequeue’s next method is called to fetch the Message object. The next method is used to fetch the message object. If you’re interested, do your own research. To summarize, create a Looper (message loop) object with looper.prepare () and execute the message loop with looper.loop (). Looper.prepare() and looper.loop () usually come in pairs. All right, come back and go through a series of judgments and come here, very important

msg.target.dispatchMessage(msg);
Copy the code

MSG. Target is a handler, so the meaning of this code is to call handler’s dispatchMessgage method to distribute messages, so see the source code of dispatchMessage method, BELIEVE that the answer is about to be opened

public void dispatchMessage(Message msg) {
    if(msg.callback ! =null) {
        handleCallback(msg);
    } else {
        if(mCallback ! =null) {
            if (mCallback.handleMessage(msg)) {
                return; } } handleMessage(msg); }}Copy the code

The callback field assigned to message is not found in the code trace above, so we will ignore it and default callback to empty, which must be the handleMessage method.

The Message object is passed to the handleMessage method.

/** * Subclasses must implement this to receive messages. */
public void handleMessage(Message msg) {}Copy the code

HandleMessage is an empty method that needs to be overridden.

At this point, the sky is vast. Switching from child thread to main thread perfectly, I have to say how wonderful the Android source code design is. This is the handler using sendMessage method to send messages source analysis.

Why do I say that? Because there’s another way that handler can send messages, and that’s the POST method, so understand that. The callback field of the message can be resolved. See the post method source code

public final boolean post(Runnable r)
{
   return  sendMessageDelayed(getPostMessage(r), 0);
}
Copy the code

Take an object that implements the Runable interface and pass it to the getPostMessage() method. Follow up with the getPostMessage() method

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}
Copy the code

A callback that wraps Runable as a message. So, if we had sent the message using the POST method and the callback field was not empty, the handleCallback() method would be executed instead of the handleMessage method.

The handleCallback method is as follows:

private static void handleCallback(Message message) {
    message.callback.run();
}
Copy the code

We call the run method directly, which means that we can do UI operations directly in the run method.

We found that the sendMessageDelayed method was eventually called regardless of whether the post method or sendMessage method was used to send the message. Handler adds the message to the MessageQueue in the same process, and then Looper continuously takes out the message from MessageQueue, and the handler distributes the message and processes the message, thus forming a perfect Android message mechanism system.

To conclude, the main thread creates a Handler that associates Looper with MessageQueue. After executing the business logic in the child thread to get the data, we need to switch to the main thread. We create a Message object, wrap some data, and then call Handler’s sendMessage method to send the Message to the MessageQueue Message queue. Miraculously, the target field of Message assigns a value to Handler, which means that the Handler object follows the Messgae object into the MessageQueue Message queue. When the program starts, Looper calls the loop method to retrieve messages from MessageQueue. Once Messgae enters the MessageQueue, Looper retrieves the message from the MessageQueue, and the Handler wrapped in Messgae, DispatchMessage is called to distribute the message, pass it to the handleMessage method, and then switch to the main thread. This is the messaging mechanism.