「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」
Handler
handler是一套Andorid消息传递机制。
handler有两个主要用途:
- 安排Message和runnables在未来某个时刻执行
- 将要在不同于自己的线程上执行的操作排入队列
(在多个线程并发跟下UI的同时保证线程的安全)
相关概念
概念 | 定义 | 作用 | 备注 |
---|---|---|---|
主线程 | 处理UI相关操作 | 通信媒介为Handler | |
子线程 | 执行耗时任务 | ||
消息Message | 线程间通信的数据单元 | 存储需要处理的通信信息 | Handler中接收和处理的消息对象 |
消息队列MessageQueue | 先进先出的消息队列 | 存储Handler发送过来的消息 | 每个线程只能有一个 |
处理者Handler | 主线程与子线程的通信媒介消息的主要处理者 | 将消息添加至消息队列处理Looper分发过来的消息 | |
循环器Looper | 消息队列和处理者的通信媒介 | 消息循环 |
\
使用方式
Handler使用方式因发送消息到消息队列的方式不同而不同,分为:
Handler.sendMessage():传入Message
Handler.post():传入Runnable
\
工作原理
本质:一个线程开启循环模式,持续监听其他线程发送过来的消息,并处理。
内存溢出问题
1.Handler匿名内部类定义在UI主线程中,使用了主线程的Looper和MessageQueue
2.MessageQueue中的Message会持有Handler对象
3.Handler对象持有外部Activity的强引用
HandlerThread
HandlerThread是一个继承自Thread的类,其中有多个便利的封装。
start后可以获取其Looper对象
其他线程使用这个对象实例化Handler,在handleMessage中执行耗时任务
异步处理,单线程
mHandlerThread = new HandlerThread("Handler-thread");
mHandlerThread.start();
mUiHandler = new Handler();
mWorkHandler = new Handler(mHandlerThread.getLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
Log.e(TAG, "消息: " + msg.what + " 线程: " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mUiHandler.post(new Runnable() {
@Override
public void run() {
textView.setText("This is work thread.");
}
});
}
};
//消息发生
Message message = Message.obtain();
message.what = 1;
message.obj = "xx";
mWorkHandler.sendMessage(message);