08. Carson Handler总结的机制源码解析
2022年4月16日
08. Carson Handler总结的机制源码解析
在阅读一次源码后模糊不懂的点,解析及影响加深
消息的处理
一.Handler是如何绑定当前线程的?
Handler初始化的时候,做了2件事
1. 指定Looper对象。
Looper对象的获取来自LocalThread.get(). Looper对象的创建来自于Looper.prepare(),使用ThreadLocal.set(new Looper()). 而ThreadLocal将Looper对象与当前线程绑定。
ThreadLocal
ThreadLocal 实例通常是希望将状态与线程相关联的类中的私有静态字段
2. 绑定MessageQueue
Handler的MessageQueue来自Looper.mQueue。而Looper.mQueue在 Looper对象创建时初始化。
总结
Handler初始化的时候从ThreadLocal,将Looper实例与线程关联,持有Looper中的MessageQueue对象的引用。所以从子线程发送的消息,可以通过MessageQueue获取Messager到looper,并使用 msg.target.dispatchMessage(msg)分发消息。
二.MessageQueue是如何将消息出队的
按照Messager对象的创建时间顺序出队。
三.Handler.dispatchMessage
1. Handler.handleCallback()
回调Runnable对象里复写的run()
2. Handler.handleMessage
复写子类handleMessage方法
消息的发送
1. 使用Message.target.dispatchMessage() 中target,Message是什么时候持有Handler引用的
Handler.enqueueMessage中,将当前Handler实例作为message的target属性。
2. enqueueMessage 消息入队
消息队列里,无消息就插入队头,有消息就按照Message入队时间插入到队列中。
之后随着Looper对象的无限循环消息,不断从消息队列中取出消息,分发到对应的handler
boolean enqueueMessage(Message msg, long when) {
                ...// 仅贴出关键代码
                synchronized (this) {
                    msg.markInUse();
                    msg.when = when;
                    Message p = mMessages;
                    boolean needWake;
                    // 判断消息队列里有无消息
                        // a. 若无,则将当前插入的消息 作为队头 & 若此时消息队列处于等待状态,则唤醒
                        if (p == null || when == 0 || when < p.when) {
                            msg.next = p;
                            mMessages = msg;
                            needWake = mBlocked;
                        } else {
                            needWake = mBlocked && p.target == null && msg.isAsynchronous();
                            Message prev;
                        // b. 判断消息队列里有消息,则根据 消息(Message)创建的时间 插入到队列中
                            for (;;) {
                                prev = p;
                                p = p.next;
                                if (p == null || when < p.when) {
                                    break;
                                }
                                if (needWake && p.isAsynchronous()) {
                                    needWake = false;
                                }
                            }
                            msg.next = p; 
                            prev.next = msg;
                        }
                        if (needWake) {
                            nativeWake(mPtr);
                        }
                    }
                    return true;
            }
post
内部根据Runnable对象而封装。 实际上是创建Messager对象,让Messager持有callback,然后在dispatchMessage的时候调用messager.callback.run();