Handler原理

Handler原理注意是消息处理机制。

  1. Message:消息的bean类,主要包含what,data, callback等信息;
  2. Handler:消息的搬运工,主要是发送和处理;
  3. MessageQueue:消息队列,主要是效果的管理;
  4. Looper:在ThreadLocal里面,用来启动MessageQueue,会调用MessageQueue的next方法。主线程默认启动了
 for (;;) {
            Message msg = queue.next(); // might block

消息队列启动。

通过Looper.loop()启动,主线程默认启动了,其他线程需要自己启动,否则不能进行消息处理。
ThreadLocal:构造方法是私有,通过获取当前的线程作为变量,保证每个线程的ThreadLocal只会是调用者的。

消息分发

如果是post还是postDelay,最终都会调用到:

public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

这是系统的开机时间,所以系统休眠了,会到延时处理失败。
消息队列排序:在MessageQueue.enqueueMessage插入的时候排序

 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;
            }

根据代码如果我们要实现一个高优先级的消息,只需要把当前时间设置会0,就会插入到堆首,以保证可以快速响应。

消息分发

根据Looper.loop()方法,会不断调用next方法。

// Return here if the message loop has already quit and been disposed.
        // This can happen if the application tries to restart a looper after quit
        // which is not supported.
        final long ptr = mPtr;
        if (ptr == 0) {
            return null;
        }

        int pendingIdleHandlerCount = -1; // -1 only during first iteration
        int nextPollTimeoutMillis = 0;
        for (;;) {
            if (nextPollTimeoutMillis != 0) {
                Binder.flushPendingCommands();
            }

            nativePollOnce(ptr, nextPollTimeoutMillis);

内部也是一个死循环,会不断暂停在nativePollOnce方法中,nextPollTimeoutMillis是暂停时间,其中的是遍历所有消息队列得到的值。-1表示永久阻塞,直至有新消息进来,唤醒。
next方法会返回下一个需要处理的消息。

if (msg != null) {
                    if (now < msg.when) {
                        // Next message is not ready.  Set a timeout to wake up when it is ready.
                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
                    } else {
                        // Got a message.
                        mBlocked = false;
                        if (prevMsg != null) {
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);
                        msg.markInUse();
                        return msg;
                    }
                } else {
                    // No more messages.
                    nextPollTimeoutMillis = -1;
                }

获取到待处理Message,Looper会调用dispatchMessage方法

  try {
                msg.target.dispatchMessage(msg);
                if (observer != null) {
                    observer.messageDispatched(token, msg);
                }
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } 

target:Message的handler,最终调用:

 /**
     * Handle system messages here.
     */
    public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

最后就会执行我们重写的handleMessage方法。

你可能感兴趣的:(Handler原理)