一、定义
Android SDK 提供给开发者方便进行异步消息处理的类
二、Handler的四大组件和运行机制

1、Handler四大组件:
(1)Message:是处理和接受消息的对象。
(2)Looper:线程持有,读取消息队列中消息,读到这个消息后交给handler来进行处理。
(3)MessageQueue:消息队列,以先进先出的方式来处理Handler发送来的消息。
(4)Handler:处理和发送消息。
2、Handler源码分析

通过Looper.myLooper()方法创建一个Looper对象,如果为 null就会抛出“在一个没有调用Looper.prepare()方法的线程内部不能创建handler”异常。然后通过mLooper.mQueue获得MessageQueue对象,这个时候意味着handler和looper共用一个消息队列。
然后看一下消息发送源码,

其实这个消息队列包括两种操作插入和读取,需要注意这个读取本身还伴随着删除操作。另外消息队列内部并不是用队列实现的,而是用单链表实现的。
先看一下插入操作queue.enqueueMessage()的代码实现,

还有一个方法读取next(),

再看一下looper如何管理MessageQueue。
首先看一下Looper中的prepare方法,他的内部其实是通过一个Thread Local容器来存取looper对象的,为什么要用ThreadLocal来存取呢?因为这样可以确保每一个线程获取到的looper都是唯一的,如果获取到的looper不为null就抛出异常,否则就创建一个looper对象存到threadLocal中。


网友评论