一、消息机制的角色分析
首先我们介绍一下消息机制的几位主人公,正是有它们的通力合作,消息机制才能正常的运行:
1、Handler:处理器,负责的内容是消息的发送和具体处理流程,一般使用时由开发者重写handleMessage函数,根据自定义的不同message做不同的UI更新操作;
2、Message:消息对象,代表一个消息实体,存放消息的基本内容;
3、MessageQueue:消息队列,按顺序存放消息实体,由单链表实现,被Looper(4)所使用(一个Looper具有一个消息队列);
4、Looper:循环器,也是我们的消息机制的主角,一个线程至多具有一个并且与线程一一对应(如何理解等会来说),负责的内容是不断从消息队列取出放入的消息并且交由消息对应的Handler进行处理(Handler的具体handleMessage操作);
5、ThreadLocal:线程本地数据,是一个线程内部的数据存储类,为每个线程存储属于自己的独立的数据。
二、消息机制总览
我们来用最简短的语言说明一下消息循环的整个过程,有个整体性的认识。
1、首先,我们知道ThreadLocal是线程内部的数据存储类,一个线程对应一个自己独一无二的数据,而我们的主角Looper就是这样一个对象,每个线程都可以有自己独一无二的Looper,而Looper自己具有一个属于自己的MessageQueue,它不断地从MessageQueue中取Message(注意,Looper的代码是运行在自己对应的线程中的),如果MessageQueue中没有消息,Looper只会不断地循环尝试取消息(阻塞)。
2、这时,我们在主线程创建了Handler对象,它需要它所在的线程(这里是主线程)所拥有的Looper对象(也就是说,没有Looper的线程创建不了Handler,后面我们也会看到具体代码),一旦我们用Handler发送了消息(可以在别的线程中,这里假设在某个子线程中),Handler就会把这个消息放入自己拥有的Looper对象的属于这个Looper对象的MessageQueue中(这句有点拗口,就是放入Looper的MessageQueue中)。
3、我们已经知道Looper会不断地尝试从自己的MessageQueue中取出消息,我们刚刚放入的消息立刻被Looper取出来了,它得到了消息就执行了发出消息的Handler(也就是2过程我们所创建的)的消息处理函数handleMessage,我们编写的UI更新操作就在Looper对象的代码中执行了,而我们刚才也说了这个Looper运行在我们创建Handler的线程中的,也就是主线程(UI线程),那这样一来就达到了我们的目标,成功的把代码执行从子线程切换到了主线程中,这个过程我们也就有个总览了,