在 Android 中,Handler 是用于在不同线程之间传递消息和执行任务的机制,尤其是常用于主线程(UI线程)和工作线程之间的通信。它与 MessageQueue 和 Looper 紧密协作,以实现异步处理和更新 UI 的功能。
1、核心组件
- Message:是用来传递数据的基本单位。
每个
Message包含:what: 一个整型标识符,用于标识消息的类型。
arg1、arg2: 可选的整型参数,用来传递数据。
obj: 一个
Object类型的字段,可以用来传递复杂的数据。target: 指定处理消息的
Handler,通常由sendMessage或sendMessageAtTime自动设置。
- MessageQueue:表示是一个消息队列,用于存储待处理的消息。它通常与一个
Looper绑定,每个线程可以有一个MessageQueue。消息被发送到消息队列中,Looper会持续从队列中取出消息并分发给相应的Handler。 - Looper:表示是一个消息循环器,它负责从消息队列中取出消息,并将消息传递给相应的
Handler进行处理。每个线程通常有一个Looper,主线程默认有一个Looper,其他线程需要手动创建和准备Looper。 - Handler:是用于处理消息的工具。它通常与一个
Looper关联,用来接收并处理从消息队列中传递过来的消息。
通过
Handler可以:发送消息到队列。
定时执行任务(通过
postDelayed或sendMessageAtTime)。将耗时操作的结果返回到主线程更新 UI。
四者对应的关系:
一个线程只能有一个 Looper,并且对应一个 MessageQueue,MessageQueue 中可以有 n 条消息,并且一个 Looper 可以被 n 多个 Handler 绑定。每个 Handler 都可以向 Looper 发消息并接受消息处理逻辑。
2、工作流程
主线程和工作线程
在 Android 中,主线程(UI线程)负责管理 UI 更新,而耗时操作通常在后台线程中执行。为了更新 UI 或进行线程间的通信,需要通过消息机制来实现。
如图所示线程 A 可以表示工作线程,线程 B 表示 UI 线程。
- 发送消息:
- 消息通常由某个线程(如后台线程)通过
Handler发送到主线程或其他线程。 - 消息可以包含数据(例如
Message.obj或arg1,arg2),可以通过sendMessage()或post()方法发送。 Handler也可以发送Runnable对象,这样Runnable就会被添加到消息队列中,并在适当的时候执行。
- 消息循环:
- 主线程(UI线程)和其他线程的
Looper会运行一个无限的循环:Looper.loop(),在这个循环中不断地从消息队列中取出消息,传递给相应的Handler进行处理。
- 处理消息:
Looper会从消息队列中取出消息,并交给对应的Handler处理。每个Handler都有一个handleMessage()方法,用来处理它接收到的消息。Handler还可以通过post()或sendMessage()来在其他线程上执行任务。
3、总结
Android 的消息机制通过 MessageQueue、Looper 和 Handler 实现了线程间的通信,特别是 UI 线程和后台线程之间。它允许我们安全地在后台线程执行耗时操作,并在操作完成后通过消息机制将结果传递回主线程更新 UI。这种机制能够保证 UI 不被阻塞,同时避免线程间的直接交互带来的同步问题。