Handler源码阅读记录
Handler源码阅读记录
我们从Handler的构造函数开始,一步一步查看Handler的内部源码,看其是如何实现自身的各种功能的。
首先从构造函数开始:
可以看到Handler在构造函数里最重要的一步是要获取Looper对象,如果没有获取到Looper对象,后面所有的工作都会进行不下去;从后面的代码可以看到,Looper内的消息队列被赋值给了Handler的消息队列,意味着Handler发送消息的目的地与Looper所持有并管理的消息队列相同,所以如果Looper为空就直接抛出错误了。
从发送消息的方法可以看出就是做了将消息插入MessageQueue中的操作。MessageQueue虽然名字为队列,但其实际内部数据结构为一个单链表数据结构来维护消息列表。(单链表在插入与删除上相比队列效率更高)
在插入消息到队列的方法中还可以看到将当前Handler的实例对象赋值给了msg.target;
而我们知道MessageQueue是由Looper管理的,那么我们来看一下Looper具体是如何实现对MessageQueue的管理的。
创建Looper对象必须要调用Looper.prepare()方法,从源码中可以看到,Looper内部有一个sThreadLocal容器来存放我们的Looper,这么做的主要目的是能保证每个线程获取到的Looper都是唯一的,ThreadLocal能为每个变量在每个线程都创建一个副本,从而不同线程改变自身线程内变量的值时不会影响其他线程。
从Looper对象的构造方法中可以看到消息队列也被同时创建。
那么在myLooper()方法中,很明显就是返回ThreadLocal容器中保存的Looper对象就好了。
紧接着我们来看Looper是怎么完成对MessageQueue的管理的:
对MessageQueue的管理主要是在loop()方法中实现。
可以看到方法首先对Looper是否为空进行了判断,然后获取Looper持有的消息队列,然后再下面我们可以看到一个for的死循环,在死循环中当获取到消息后调用了msg.target.dispatchMessage()方法,而msg.target就是发送该消息的Handler对象。
然后我们回到Handler的 dispatchMessage()方法,可以看到该方法里调用了一个我们很熟悉的、经常重写的handleMessage()方法。至此其实我们整个Handler的流程已经走通了。
最后放一张Handler的流程示意图给大家辅助理解。
希望这篇文章对您有所帮助,感谢您的阅读!