Handler, Message 消息传递机制

来源:互联网 发布:mac设置用户名 编辑:程序博客网 时间:2024/06/07 17:00

Handler, Message 消息传递机制

个人理解

在创建handler之前,必须确认已经在handler所在线程中调用了Looper.prepare(),因为在handler构造函数中会判断当前线程中是否有Looper对象,没有则报异常(无法在没有调用Looper.prepare()的线程中创建handler对象)

Looper.prepare作用

1:判断当前线程中是否存在Looper对象,否则new一个ThreadLocal类型Looper对象,使得每个线程有独立的Looper,防止多线程传递消息时发生异常,是则报异常(一个线程中最多只能有一个Looper对象)。在Looper构造函数中创建了消息队列对象mQueue。

2:即1中创建了消息队列对象mQueue,将Looper和MessageQueue的对象“绑定”在一起。
在handler构造函数中,将handler所在线程中的Looper所创建的消息队列对象mQueue赋值给handler中声明的消息队列对象mQueue,将Looper,Handler,MessageQueue的对象“绑定”在一起。

发送消息:

Handler发送消息的方法经过封装调用最后跳转到sendMessageAtTime()方法(除了sendMessageAtFrontOfQueue(),这个方法将新的message放置到消息队列的头部)。将handler中声明的消息队列mQueue传入,调用enqueueMessage()方法,通过msg.target.this将调用发送消息方法的handler对象与所发送的消息“绑定”,继续调用enqueueMessage的2个参数的方法,将传入的消息以队列排列。
接下来要取出消息队列中的消息,通过Looper.loop()方法实现,获得当前线程中的Looper对象,取出它的消息队列,通过for(;;)死循环取出队列中的消息,并调用msg.target.dispatchMessage(msg)方法(msg.target即是与发送消息“绑定”的handler),将取出的消息传回handler所在线程的handlemessage(msg)方法中,在里面更新UI,完成非UI线程和UI线程间的通信,解决因线程不安全不适合在非UI线程更新UI的问题。