官方参考文档
https://developer.android.com/reference/android/os/Handler.html
原理解析
那么Handler是怎么工作的呢?这时候需要认识这三个类,分别是: Message(消息), MessageQueue(消息队列), Looper(消息循环者)。
Message :android.os.Message是定义一个Messge包含必要的描述和属性数据,并且此对象可以被发送给android.os.Handler处理。属性字段:arg1、arg2、what、obj、replyTo等;其中arg1和arg2是用来存放整型数据的;what是用来保存消息标示的;obj是Object类型的任意对象;replyTo是消息管理器,会关联到一个handler,handler就是处理其中的消息。通常对Message对象不是直接new出来的,只要调用handler中的obtainMessage方法来直接获得Message对象。
MessageQueue :MessageQueue的中文翻译是消息队列,顾名思义,它的内部存储了一组消息,以队列的形式对外提供插入和删除的工作。虽然叫消息队列,但是它的内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息。它只是用来存储消息,而并不能处理消息,Looper就填补了这个功能。
- Looper:在MessageQueue里存储了消息之后,Looper就会以无限循环的形式去查是否有新消息,如果有的话就去处理消息,否则就是一直等待着。Looper中还有一个特殊的概念就是ThreadLocal,ThreadLocal并不是线程,它是用来在每个线程中存储数据。Handler创建的时候就会采用ThreadLocal获取当前线程的Looper构造消息循环系统。还有一点非常要注意的是,工作线程是默认是没有Looper的,若要在线程中使用就需要创建Looper,否则就会抛出Can’t create handler inside thread that has not called Looper.prepare(),意思是不能创建Handler因为Looper没有执行Looper.prepare()方法,尚未初始化。而UI线程即主线程中,是默认初始化了Looper的,所以不需要再UI线程再次执行Looper.prepare()方法了。那么在工作线程中如何初始化Looper的代码如下:
new Thread("Thread#2"){
@Override
public void run(){
Looper.prepared();
Handler handler = new Handler();
Looper.loop();
};
}.start();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
工作流程
Handler的主要工作包含消息的发送与接收过程。消息的发送通过post和send的一系列方法来实现,其实post的一系列方法最终还是通过send来实现的。当Handler发送了消息之后,MessageQueue里就插入了一条消息,然后MessageQueue就会返回这条消息给Looper,Looper接收到消息之后就开始处理了,最终消息由Looper交给Handler处理,即Handler的dispatchMessage方法会被调用,这时Handler就进入了处理消息的阶段,最后经过一系列的判断之后,就会调用handleMessage()方法了。
以上就是Handler机制的基本原理,相信通过上面介绍之后,读者对Handler能够有更清楚的认识。