Personal understanding of handler

Keywords: Android

handler is sometimes used
The post and postDelayed methods perform some tasks. Here, let's take a look at what hanlder does when executing these two methods

The handler's post method will eventually call sendMessageDelayed, and the handler's postDelayed method (whether it has three parameters or two parameters) will eventually call the sendMessageDelayed method.

The sendMessageDelayed method will first determine whether there is a message queue. If it is null, an exception will be thrown. If not, execute the enqueueMessage method.

boolean enqueueMessage(Message msg, long when) {
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        if (msg.isInUse()) {
            throw new IllegalStateException(msg + " This message is already in use.");
        }

        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w(TAG, e.getMessage(), e);
                msg.recycle();
                return false;
            }

            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
            if (p == null || when == 0 || when < p.when) {
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            } else {
                // Inserted within the middle of the queue.  Usually we don't have to wake
                // up the event queue unless there is a barrier at the head of the queue
                // and the message is the earliest asynchronous message in the queue.
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }

enqueueMessage method is in MessageQueue. After the method comes in, it will first judge the target and isinuse of message.
If the target is not null and isInUser is not true, you will enter the code block of the synchronization lock (in my humble opinion, the reason for locking here is that this method will be called by the handler for many times, and there are multiple threads. For the time being, no code block can be found to support this idea). After entering, you will first judge the status of mqitting, This variable is set to true only when exiting the message queue (if the Boolean value is not set at the time of declaration, the default value is false).
If it is not true, it will go to the later judgment. You can see that the first judgment has three judgment conditions. Judge whether message is empty, whether the time is 0 and whether the time is less than the time of message.
If this judgment condition is met, the passed message will be assigned to the current message and then passed.
If it does not meet the conditions of the first judgment, it will enter else.

Let's first look at the general meaning of this comment in the code,

As you can see here, this part will insert the message into the queue until the message is at the head of the message queue.
Here is a for loop, which will get the message and judge the status of the message. This loop will not exit until the message is null or the time is less than the set time of the message (I was told that there is an infinite for loop in the handler. It seems that it is actually in the message queue). From this process, we can see how the message is executed through the two methods of post and postDelayed.

Posted by blastbum on Sat, 25 Sep 2021 20:09:39 -0700