在Android中很多耗时工作需要在子线程进行,这就避免不了在子线程更新控件,子线程处理数据并更新界面就可能出现多个线程同时更新界面导致界面混乱.官方给出的处理方案就是使用Handler对所有需要处理的事件进行排队处理,handler也可以说是安卓子线程更新界面最安全的方式.
Handler机制主要组成成员如下:
(1)Handler:处理消息主体.
(2)Message:消息载体
(4)MessageQueue:消息队列,用于消息排队,遵循先入先出原则.
(3)Looper:给线程实现一个轮询消息.这是一个死循环,不停从MessageQueue中取出消息,交由Handler处理.
一.Handler的使用
1.主线程使用Handler
具体流程如下:
(1)主线程创建Handler,重写handleMessage()方法;
(2)子线程使用handler.sentMessage(message)方法发送消息
(3)在handlerMessage()方法中对接收到的message进行接收,进行界面更新等操作.
2.子线程使用Handler
Android中子线程创建Handler,从主线程向子线程发送消息代码如下:
具体流程如下:
(1)调用Looper.prepare创建子线程的Looper.
(2)在子线程创建Handler,重写handleMessage()方法.
(3)最后调用Looper.loop启动消息轮询.
(4)使用handler.sendMessage(message),向子线发送消息[注:发送方法有很多,使用sendMessage指代发送方法]
(5)handleMessage()方法中处理消息.
二.Handler消息机制分析
消息处理主要过程简图如下:
接下来按照子线程使用Handler的顺序来分析整个过程,
1.首先看Looper.paper()方法:
从上图看出,prapare使用ThreadLocal创建了一个Looper,这里的ThreadLocal是Looper的一个静态对象,实际就是一个map,使用线程Id作为Key,Looper对象为value,保证所有当前线程有且仅有一个Looper对象,如下图所示并且在Looper的构造方法中创建了MessageQueue对象,.
2.接下来是创建Handler:
从上图得出,handler创建时会从利用ThreadLocal中获取当前线程的Looper,并赋值给Handler中的全局变量mLooper,因为之前调用了Looper.prapare方法在Thread中添创建了Looper对象,所以此处不会返回为空对象.
3.下面调用Looper.loop(),该方法比较长,关键代码如下:
该方法中使用一个死循环,不停从MessageQueue中取出msg,Message中的target对象就是Handler对象本身,所以最后调用handler的dispatMessage方法,最后在dispatMessage调用了handlerMessage方法.
4.最后是Message的sendMesage方法:
从上图看出最后调用的是Handler中的MessageQueue的enqueueMessage,该方法具体实现因为涉及到同步的问题代码比较长,具体所做就是往这个队列中加入message.
以上就是Handler的使用与源码的大致分析,第一次写博客,希望大家能提供宝贵的意见,也希望能帮助大家对Handler的机制有进一步的了解.