Handler
安卓信息传递机制/异步通信机制
作用 在多线程应用场景,将工作线程中需要更新UI的操作信息传递到UI主线程从而实现信息异步通信。
特点 为保证线程安全,使用Handler
名词解释
主线程 应用程序第一次启动同时开启的主线程;负责处理UI相关事件
子线程 后续人为手动开启的线程;负责进行耗时操作
消息 线程间通信的数据单元;负责存储通信信息
消息队列 队列数据结构;存储Handler发来的消息
处理者 主线程与子线程的通信媒介,线程消息的主要处理者;负责添加消息到消息队列、处理循环器分派过来的消息
循环器 消息队列与处理者的通信媒介;负责消息循环(获取消息:循环取出消息队列的消息;消息分发:将取出的消息发送给对应处理者)
注:每个线程只能拥有一个循环器;一个循环器可以绑定多个线程的Handler(即多个线程可以向一个循环器消息队列发送信息)
使用方式
Handler.sendMessage()
新建Handler子类(内部类)
①自定义Handler子类
class mHandler extends Handler {
// 通过复写handlerMessage() 从而确定更新UI的操作
@Override
public void handleMessage(Message msg) {
...// 需执行的UI操作
}
}
②在主线程创建Handler、工作线程创建消息实例
private Handler mhandler = new mHandler();
Message msg = Message.obtain(); // 实例化消息对象
msg.what = 1; // 消息标识
msg.obj = "AA"; // 消息内容存放
③工作线程中,通过Handler发送消息
mHandler.sendMessage(msg);
④开启工作线程(AsyncTask、Thread、Runnable)
匿名内部类
①主线程通过匿名内部类创建Handler实例
private Handler mhandler = new Handler(){
// 通过复写handlerMessage()从而确定更新UI的操作
@Override
public void handleMessage(Message msg) {
...// 需执行的UI操作
}
};
②创建消息对象
Message msg = Message.obtain(); // 实例化消息对象
msg.what = 1; // 消息标识
msg.obj = "AA"; // 消息内容存放
③在工作线程用Handler发送消息
mHandler.sendMessage(msg);
④开启工作线程(同上④)
Handler.post()
①主线程创建Handler实例
private Handler mhandler = new mHandler();
②在工作线程发送消息到信息队列、指定UI操作
mHandler.post(new Runnable() {
@Override
public void run() {
... // 需执行的UI操作
}
});
③开启工作线程
上述两种操作不同的是:post是由工作线程规定操作,交由UI线程执行;而sendMessage是由主线程规定收到信息操作,工作线程只负责发送信息
工作原理
工作流程分析
异步通信准备
在主线程创建:①循环器对象(Looper)②消息队列对象(MessageQueue)③Handler对象
注:创建消息队列后,循环器自动进入消息循环;循环器和消息队列都属于主线程
消息入队
工作线程通过Handler发送消息到消息队列
消息循环
①消息出队:循环器循环取出消息队列中的消息
②消息分发:循环器将取出的消息发送给创建该循环器的Handler
注:若循环过程中消息队列为空,则线程阻塞
消息处理
Handler接收消息后,依据消息信息执行UI操作
对应关系:
一个线程只能绑定一个循环器,但可有多个Handler
一个循环器可绑定多个Handler
一个Handler只能绑定一个循环器