Handler的工作流程类比成【传送带】的运作流程
总共两个步骤 ->发送消息 和 调度消息
1.发送消息
Handler的不管是sendxxx还是postxxx方法 最终都会调用
enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis)
enqueueMessage 方法中会掉用 MessageQueue 的
enqueueMessage(Message msg, long when)
对比时间按时间先后,把消息插入到消息队列,以上完成消息的发送
MessageQueue 是个优先级队列 按照时间先后顺序排队
2. 调度消息
Looper 轮询器 取消息
通过loop()
方法开启 轮询 消息队列MessageQueue.next()方法 。
在 next()方法中轮询消息队列中的消息Messagae。
首先会调用一个系统的native方法,nativePollOnce()检测当消息队列是否为空。如果为空会进入等待,不为空会 则会判断轮询到的消息需要发送的时间是否到了当前时刻,如果达到了就取出消息,没有则进行下一轮循环。
取出消息后 调用msg.target.dispatchMessage()
完成消息调度
这里 msg.target就是Handler
---------------------以上就是整个流程-----------------------
附加
Q:一个线程有几个Looper?如何保证?为什么?
A:1个 ,
通过静态方法prepare()
创建Looper
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
sThreadLocal.get()获取是否已经存了Looper,已经存在了就会抛出异常Only one Looper may be created per thread,否则 就设置一个Looper到ThreadLocal.ThreadLocalMap 的中
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
set的时候首先获取当前线程 ,然后获取线程的threadLocals变量,一个线程只有一个ThreadLocalMap ,所以值对应一个Looper
这个ThreadLocalMap 是 ThreadLocal静态内部类
网友评论