八、Handler机制源码解析

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

猜你喜欢

转载自blog.csdn.net/aa375809600/article/details/78018312