Handler 消息机制,与Looper结合使用Handler

Handler 是 Android 中的一个类,用于实现线程之间的消息传递和任务调度。它基于消息队列(Message Queue)和消息循环(Message Loop)的机制,允许你在一个线程中创建 Handler 对象,用于发送和处理消息。

以下是 Handler 消息机制的基本原理:

  1. 消息队列(Message Queue):每个 Handler 对象都关联一个消息队列,用于存储待处理的消息。消息队列采用先进先出(FIFO)的方式,即先发送的消息先被处理。

  2. 消息循环(Message Loop):每个线程只能有一个消息循环,它负责从消息队列中取出消息,并将其传递给对应的 Handler 进行处理。消息循环以无限循环的方式运行,不断地从消息队列中获取消息并处理,直到消息队列为空或被终止。

  3. 消息对象(Message):消息对象封装了要处理的信息和相关的数据。它包含一个标识符(what),用于指定消息类型或操作代码,以及可选的附加数据(Bundle 对象)。

  4. 发送消息:通过 Handler 对象的 sendMessage() 或 post() 方法,可以向消息队列发送消息。你可以指定消息类型、延迟时间、附加数据等。

  5. 处理消息:在 Handler 对象中,你可以重写 handleMessage() 方法,用于处理接收到的消息。根据消息的类型或标识符,你可以执行相应的操作。

通过使用 Handler 消息机制,你可以在不同的线程之间进行通信和任务调度。例如,在主线程(UI 线程)中创建一个 Handler 对象,你可以将消息发送到该 Handler,在 UI 线程中处理这些消息以更新用户界面。另外,你还可以在后台线程中创建 Handler 对象,用于执行异步任务并将结果发送回主线程。

这种消息机制使得线程间的通信更加简单和安全,避免了直接操作共享数据带来的并发问题。

Handler 与 Looper 紧密相关,Looper 负责消息队列的循环。当你创建一个 Handler 实例时,它默认与当前线程的 Looper 关联。如果有多个 Handler 实例,它们将共享同一个 Looper。Handler 可以发送消息(Message)和Runnable对象到消息队列中。这些消息和Runnable对象将在 Looper 的循环中按顺序执行。当 Handler 发送消息或Runnable对象时,它们被放入一个消息队列中。每个线程有一个消息队列,用于存储待处理的消息和Runnable对象。Looper 从消息队列中取出消息并执行它们,或者将它们传递给 Handler 的 handleMessage 方法。消息(Message)是一个包含 what、arg1、arg2 和一个可选项 obj(通常是 Bundle)的对象。Runnable 对象是一个实现了 Runnable 接口的对象,可以直接发送到消息队列中执行。同步消息(SYNC)会阻塞消息队列,直到消息处理完成。异步消息(ASYNC)不会阻塞消息队列,消息处理是并发的。Handler 的 handleMessage 方法用于处理接收到的消息。你可以重写 handleMessage 方法来定义如何处理不同类型的消息。Handler 通常用于更新 UI 元素,因为 UI 更新必须在主线程(UI 线程)中执行。它也用于在后台线程和主线程之间传递数据,或者在不同的后台线程之间进行通信。我们使用的时候应该避免在 Handler 中创建无限循环或者长时间运行的任务,这可能会导致应用程序无响应(ANR)。确保在正确的线程中使用 Handler,否则可能会导致线程间通信问题。

与Looper结合使用Handler消息机制的步骤如下:

1. 创建Handler对象和Looper对象:在目标线程中创建一个Looper对象,并将其启动,然后创建一个Handler对象与该Looper相关联。

Looper.prepare(); // 创建并启动Looper
Handler handler = new Handler();
Looper.loop(); // 进入Looper的消息循环


2. 发送消息或Runnable对象:在源线程中,通过Handler对象发送消息或Runnable对象到目标线程的消息队列。

handler.sendEmptyMessage(MSG_WHAT); // 发送一个消息
handler.post(runnable); // 发送一个Runnable对象


3. 处理消息:在目标线程中,通过重写Handler的`handleMessage()`方法来处理收到的消息。

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_WHAT:
                // 处理消息
                break;
            // 其他case...
        }
    }
};


4. 退出消息循环:如果需要退出消息循环,可以调用Looper的`quit()`或`quitSafely()`方法。

looper.quit(); // 退出消息循环


在使用Looper和Handler时,需要注意以下几点:

- 通常情况下,Looper和Handler是在同一线程中使用的,例如在主线程中。但也可以在其他线程中使用,只需在该线程中创建Looper和Handler即可。

- Looper的`loop()`方法会进入一个无限循环,不断从消息队列中取出消息并分发给对应的Handler进行处理。因此,如果不需要继续处理消息,需要手动退出消息循环。

- 在与Looper结合使用时,Handler的构造函数可以接收一个Looper对象作为参数,来关联指定的Looper。例如:`Handler handler = new Handler(myLooper);`

- 如果在子线程中使用Looper和Handler,需要在子线程的`run()`方法中创建Looper并调用`loop()`方法,以确保消息循环在子线程中执行。

总结起来,与Looper结合使用Handler消息机制可以实现在不同线程间进行消息传递和异步处理。通过创建Looper对象和Handler对象,并在目标线程中进入消息循环,可以实现消息的接收和处理。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值