一、Android消息机制的作用
Android的消息机制主要是指Handler的运行机制,它的作用是提供”在某个具体的线程中执行任务”的功能。

二、Android消息机制在更新UI上的应用
Android只能在主线程中访问UI,因为Android的UI控件不是线程安全的。为什么不加入锁机制呢?因为那样会降低UI访问效率。
可是有时候要进行耗时操作,主线程又不能进行耗时操作,不然会ANR。这时候我们就要开启子线程进行耗时操作。
在子线程耗时操作完成后,要更新UI,这时候就要用到消息机制回到主线程了。

三、Android消息机制的具体实现
1、ThreadLocal
当某些数据是以线程为作用域并且不同线程拥有不同副本的时候,就可以考虑使用ThreadLocal。
我们在不同的线程往ThreadLocal里放入一个对象,那么在不同的线程里拿取对象时,拿到的就是专属于这个线程的对象。
比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程中的存取。
Looper只需要在自己的线程中工作,不需要在别的线程中引用。

ThreadLocal的使用:

android 消息机制封装 android系统消息机制_Android

2、在特定的线程里处理消息
我们首先需要在一个线程里初始化Looper,并开始循环取消息

Looper.prepare();
Looper.loop();

初始化Looper的时候也就初始化了一个MessageQueue

android 消息机制封装 android系统消息机制_Android_02


loop()会调用MessageQueue的next()来获取新消息,而next()是一个阻塞操作,当没有消息时,next会一直阻塞在那里。如果MessageQueue的next()返回了新消息,Looper就会处理这条消息。msg.target.dispatchMessage(msg),这里的msg.target就是发送这条消息的Handler对象,这样Handler发送的消息最终又交给它的dispatchMessage()处理了。而loop()方法是运行在调用loop()方法的线程里,所以就将要做的任务切换到这个线程中来了。

3、向特定的线程发消息

android 消息机制封装 android系统消息机制_Android_03


在一个线程中初始化Handler时,会取出当前线程的Looper对象让Handler持有,从而Handler持有这个Looper的MessageQueue对象,从而Handler能够调用MessageQueue的enqueueMessage(),向MessageQueue中添加消息。4、Handler处理消息的过程

android 消息机制封装 android系统消息机制_Android_04

当message有回调时,就先执行回调,没有的话就不执行;
然后如果有CallBack接口,就先调用Handler的CallBack接口的处理方法,如果它表示已经处理完毕,那么就不会往下继续处理了;
然后调用Handler的处理方法

android 消息机制封装 android系统消息机制_消息机制_05

5、如何退出Looper
Looper也是可以退出的,Looper提供了quit和quitSafely来退出一个Looper,二者的区别是:quit会直接退出Looper,而quitSafely只是设定一个退出标记,然后把消息队列中的已有消息处理完毕后才安全退出。Looper退出后,通过Handler发送的消息会失败,这个时候Handler的send方法会返回false。
loop方法是一个死循环,唯一跳出循环的方式是MessageQueue的next方法返回了null。当looper的quit方法被调用时,Looper就会调用MessageQueue的quit或者quitSafely方法来通知消息队列退出,当消息队列被标记为退出状态时,它的next方法就会返回null。


android 消息机制封装 android系统消息机制_Android_06