Handler机制的主要对象有Handler、Looper、MessageQueue、Thread、ThreadLocal.下面我按照咱们使用Handler程序执行的思路.来给大家捋一下.
[]()
可以看到.这个new Handler的时候.主要是获取Looper里面的MessageQueue引用.然后给mCallback 和mAsynchronous 赋值.构造函数传Looper的也是大同小异.所以不管怎么样我们都要构建一个Looper
构建prepare的方法.
public static void prepare() {
prepare(true);
}
调用的是:
有一个sThreadLocal.把Looper set进去了.(后面我会详细介绍ThreadLocal)接下来我们看一下new Looper
这个地方可以做一波总结了:其实Looper.prepare做的操作也很简单.就是new了一个Looper.Looper里面有new MessageQueue.然后获取了一个当前Thread的引用对象.然后set进ThreadLocal.接下来就可以发消息了.
无论何种发送消息的法师最后都是通过sendMessageAtTime这个基础方法发送的.而这里也只是做了一个基础的入队列操作
序号一:这里是取出从looper中取出messageQueue
序号二:发送到message的target.这个target,实际是在发送时.发送它的handler。
再来看看dispatchMessage:
看到了最喜欢的最会用的简单api handleMessage我就问你高兴不高兴.一套带走了Handler的逻辑.接下来回答一下面试常问的问题
前面我们讲到.Looper.prepare.实际是
我们看看这个sThreadLocal.
static final ThreadLocal sThreadLocal = new ThreadLocal();
这是在Looper中的定义.,这个地方的意义其实也很明了.就是所有的Looper都是通过这个对象set的,看看set方法
先看看getMap
前面两段代码就是从thread获取一个ThreadLocalMap.然后把value放进去.这个value此时是指我们的Looper.又因为Looper全部都是放进同一个sThreadLocal.这里有两个重要概念.thread和looper的关系是怎么样的.
thread有唯一ThreadLocalMap. 所有的looper都通过sThreadLocal设置.其实它也只充当ThreadLocalMap的key值.每个线程都有一个ThreadLocalMap.sThreadLocal不变.所以新的Looper放进来.这时候ThreadLocalMap中新的Looper会覆盖旧的Looper,所以一个线程只能有一个Looper
这其实是一个生产者和消费者模式的复杂版本.即是 Handler生成message.MessageQueue充当运输.Looper取出消息给handleMessage