Handler机制的主要对象有Handler、Looper、MessageQueue、Thread、ThreadLocal.下面我按照咱们使用Handler程序执行的思路.来给大家捋一下.
1.在子线程使用Handler
[]()
可以看到.这个new Handler的时候.主要是获取Looper里面的MessageQueue引用.然后给mCallback 和mAsynchronous 赋值.构造函数传Looper的也是大同小异.所以不管怎么样我们都要构建一个Looper
2.构建Looper
构建prepare的方法.
public static void prepare() {
prepare(true);
}
调用的是:
有一个sThreadLocal.把Looper set进去了.(后面我会详细介绍ThreadLocal)接下来我们看一下new Looper
这个地方可以做一波总结了:其实Looper.prepare做的操作也很简单.就是new了一个Looper.Looper里面有new MessageQueue.然后获取了一个当前Thread的引用对象.然后set进ThreadLocal.接下来就可以发消息了.
3.通过Looper.myLooper获取Looper对象
easy.刚才set了.现在get
4.接下来就该发消息.sendMessage
无论何种发送消息的法师最后都是通过sendMessageAtTime这个基础方法发送的.而这里也只是做了一个基础的入队列操作
5.接下来看看取的方法.其实就是loop取出来
序号一:这里是取出从looper中取出messageQueue
序号二:发送到message的target.这个target,实际是在发送时.发送它的handler。
再来看看dispatchMessage:
看到了最喜欢的最会用的简单api handleMessage我就问你高兴不高兴.一套带走了Handler的逻辑.接下来回答一下面试常问的问题
6.一个Handler里面有几个Looper.
前面我们讲到.Looper.prepare.实际是
我们看看这个sThreadLocal.
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
这是在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