Android Handler 消息机制

136 阅读3分钟

在 Android 中,Handler 是用于在不同线程之间传递消息和执行任务的机制,尤其是常用于主线程(UI线程)和工作线程之间的通信。它与 MessageQueueLooper 紧密协作,以实现异步处理和更新 UI 的功能。

1、核心组件

  • Message:是用来传递数据的基本单位。

每个 Message 包含:

what: 一个整型标识符,用于标识消息的类型。

arg1、arg2: 可选的整型参数,用来传递数据。

obj: 一个 Object 类型的字段,可以用来传递复杂的数据。

target: 指定处理消息的 Handler,通常由 sendMessagesendMessageAtTime 自动设置。

  • MessageQueue:表示是一个消息队列,用于存储待处理的消息。它通常与一个 Looper 绑定,每个线程可以有一个 MessageQueue。消息被发送到消息队列中,Looper 会持续从队列中取出消息并分发给相应的 Handler
  • Looper:表示是一个消息循环器,它负责从消息队列中取出消息,并将消息传递给相应的 Handler 进行处理。每个线程通常有一个 Looper,主线程默认有一个 Looper,其他线程需要手动创建和准备 Looper
  • Handler:是用于处理消息的工具。它通常与一个 Looper 关联,用来接收并处理从消息队列中传递过来的消息。

通过 Handler可以:

发送消息到队列。

定时执行任务(通过 postDelayedsendMessageAtTime)。

将耗时操作的结果返回到主线程更新 UI。

四者对应的关系: whiteboard_exported_image.png 一个线程只能有一个 Looper,并且对应一个 MessageQueue,MessageQueue 中可以有 n 条消息,并且一个 Looper 可以被 n 多个 Handler 绑定。每个 Handler 都可以向 Looper 发消息并接受消息处理逻辑。

2、工作流程

whiteboard_exported.png

主线程和工作线程

在 Android 中,主线程(UI线程)负责管理 UI 更新,而耗时操作通常在后台线程中执行。为了更新 UI 或进行线程间的通信,需要通过消息机制来实现。

如图所示线程 A 可以表示工作线程,线程 B 表示 UI 线程。

  1. 发送消息:
  • 消息通常由某个线程(如后台线程)通过 Handler 发送到主线程或其他线程。
  • 消息可以包含数据(例如 Message.objarg1arg2),可以通过 sendMessage()post() 方法发送。
  • Handler 也可以发送 Runnable 对象,这样 Runnable 就会被添加到消息队列中,并在适当的时候执行。
  1. 消息循环:
  • 主线程(UI线程)和其他线程的 Looper 会运行一个无限的循环:Looper.loop(),在这个循环中不断地从消息队列中取出消息,传递给相应的 Handler 进行处理。
  1. 处理消息:
  • Looper 会从消息队列中取出消息,并交给对应的 Handler 处理。每个 Handler 都有一个 handleMessage() 方法,用来处理它接收到的消息。
  • Handler 还可以通过 post()sendMessage() 来在其他线程上执行任务。

3、总结

Android 的消息机制通过 MessageQueueLooperHandler 实现了线程间的通信,特别是 UI 线程和后台线程之间。它允许我们安全地在后台线程执行耗时操作,并在操作完成后通过消息机制将结果传递回主线程更新 UI。这种机制能够保证 UI 不被阻塞,同时避免线程间的直接交互带来的同步问题。