
2.4 Handler消息传递机制
假如你的应用需要联网读取数据,这是个比较耗时的操作,你不能把这些耗时的操作放在主线程里,因为这样会出现界面假死现象,所以必须把这些耗时的操作放在子线程中。但由于子线程又涉及UI的更新操作,而UI必须由主线程访问。这时,接收子线程发送过来的数据,并配合主线程更新UI的Handler便出现了。本节将介绍Handler的消息传递机制。
2.4.1 认识Handler
对于Handler,它的主要任务就是接收从子线程传递过来的数据、消息,并在主线程中处理获取到的消息。
Handler运行在主线程中,它与子线程通过Message对象来传递数据。分两步:子线程通过sendMessage()方法传递Message对象,里面包含数据;主线程中的Handler接收数据,并配合主线程更新UI。
Handler是通过回调的方式来处理子线程传递过来的数据的。开发者只要重写Handler类中的处理消息的方法,当子线程中的消息被发送时,Handler类中处理消息的方法将被自动调用。
用于发送、处理消息的方法如下:
void handleMessage(Message msg)——处理消息的方法。该方法通常用于被重写。
final boolean hasMessages(int what)——检查消息队列中是否包含what属性为指定值的消息。
final boolean hasMessages(int what, Object object)——检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息。
多个重载的Message obtainMessage()——获取消息。
sendEmptyMessage(int what)——发送空消息。
final boolean sendEmptyMessageDelayed(int what, long delayMillis)——指定多少毫秒之后发送空消息。
final boolean sendMessage(Message msg)——立即发送消息。
final boolean sendMessageDelayed(Message msg, long delayMillis)——指定多少毫秒之后发送消息。
2.4.2 使用Handler
上节已经简单介绍了Android Handler的作用以及Handler类中常用的回调方法。本节将通过一个简单的例子来进一步学习Android Handler的使用。

上面的XML界面文件很简单,只是在一个空白的界面布局中添加了一个文本框,用于显示从SD卡里读取到的内容。



上面的代码中,定义了一个Handler类,重写了handleMessage回调方法。该方法实现当接收到的消息标识为0x123时,将接收到的消息作为界面中的EditText的显示内容。这里使用的是回调机制,当子线程发送消息时,handleMessage方法将会被自动回调。之所以在handleMessage方法中能够访问Activity中的组件,是因为该方法是在主线程中被调用的。
程序中为EditText注册了触摸屏监听器,该监听器实现启动一条子线程,用于读取SDCard中的aa.txt文本并将读取到的内容封装在消息对象中,如代码行msg.obj=res。然后通过handler.sendMessage(msg)发送消息,此处使用的handler即为之前所定义的Handler类的对象。这样,在该线程中所发送的消息将会被这个handler所接收。
运行效果如图2.4所示。

图2.4 借助Handler更新UI