Handler使用
一、相关概念
Handler是一套消息传递机制,通常的作用是在多线程的应用场景中,将子线程(工作线程)中需要更新UI的相关信息传递到主线程,从而实现工作线程对UI的更新。
概念 | 定义 | 作用 | 备注 |
---|---|---|---|
主线程 (UI线程、MainThread) |
应用程序首次开启时会自动开启一条线程,其实就是主线程 | 处理和UI相关操作 | 不可进行耗时操作 |
子线程 (工作线程) |
手动开启的线程 | 主要进行耗时操作 | 子线程通过Handler与主线程通信 |
消息 (Message) |
线程间通信的数据单元 | 存储通信信息 | |
消息队列 (Message Queue) |
一种先进先出的数据结构 (底层是单向链表实现) |
存储和管理Handler发送来的消息 | 创建Looper时同时创建Message Queue |
处理者 (Handler) |
子线程和主线程通信的媒介 线程信息的主要处理者 |
添加消息队列 处理Looper分发过来的消息 |
创建Handler时,Looper必须存在 |
循环器 (Looper) |
消息队列与Handler的通信媒介 | 无限循环 获取消息:从消息队列取出消息 分发消息:将取出消息分发给对应Handler |
每个线程最多只能对应一个Looper(只能创建一次) 一个Looper可以被多个Handler绑定 一个Handler只能绑定一个Looper |
二、使用方式
Handler的使用方式可以根据发送消息的方式不同而分为两种:
Handler.sendMessage和Handler.post()
三、使用步骤
方式一:使用Handler.sendMessage()
根据创建Handler的方式不同,又可分两种:创建Handler子类、使用匿名类,但本质都是相同的,都是继承Handler类创建子类
-
创建Handler子类:
1.自定义Handler子类,并重写handleMessage()方法
static class MyHandler extends Handler {
WeakReference<Activity> weakReference;
public MyHandler(Activity activity){
weakReference = new WeakReference<>(activity);
}
//重写handleMessage()方法
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (weakReference.get() == null) {
//activity被回收
return;
}
//执行的UI操作
}
}
2.主线程创建Handler实例
private MyHandler myHandler = new MyHandler(this);
3.在子线程中创建需要发送的消息对象
Message msg = Message.obtain();
msg.what = 1;
4.在子线程中通过Hander发送消息到消息队列
myHandler.sendMessage(message);
5.启动子线程
-
使用匿名类:
1.在主线程中通过匿名内部类创建Handler类对象
Handler mhandler = new Handler(){
//重写handleMessage()方法
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//执行的UI操作
}
};
2.在子线程中创建需要发送的消息对象
Message msg = Message.obtain();
msg.what = 1;
3.在子线程中通过Hander发送消息到消息队列
mhandler .sendMessage(msg);
4.启动子线程
方式二:使用Handler.post()方法
1.在主线程中创建Handler实例
private Handler mhandler = new Handler();
2.在子线程中使用Handler.post()发送消息
mhandler.post(new Runnable() {
@Override
public void run() {
//执行的UI操作
}
});
3.启动子线程