Android中Handler通信机制

一、Handler机制中基本概念

  1. 消息队列(Message Queue):Handler 对象关联着一个消息队列,类似于一个邮箱,用来存放待处理的消息。

  2. Looper 循环:每个线程中都有一个 Looper 对象,负责循环地从消息队列中取出消息,并将其发送给相应的 Handler。

  3. 消息处理:当 Handler 发送消息时,消息被加入到关联的消息队列中。Looper 循环不断地从消息队列中取出消息,然后将其分发给对应的 Handler,并调用 Handler 的 handleMessage() 方法来处理消息。

  4. 处理器Hnadler:处理消息。

二、使用Handler机制目的

在Android中,主线程(UI线程)不能进行耗时操作,否则会导致界面卡顿。通过Handler,可以将耗时操作放到后台线程中执行,并在执行完成后,通过Handler将结果返回到主线程更新UI。也可以进行不同线程间通信。

三、实例

在主线程中更新 UI 的文本框内容,但是耗时的任务需要在后台线程中执行。这时就可以使用 Handler 机制来实现。

// 创建一个新线程,用于执行耗时任务
Thread backgroundThread = new Thread(new Runnable() {
    @Override
    public void run() {
        // 模拟耗时操作
        try {
            Thread.sleep(3000); // 模拟耗时操作,这里休眠3秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 创建一个消息对象,用于通知主线程更新 UI
        Message message = new Message();
        message.what = UPDATE_UI;
        message.obj = "耗时任务执行完成";
        
        // 发送消息到主线程的消息队列中
        handler.sendMessage(message);
    }
});
backgroundThread.start();

// 在主线程中创建一个 Handler 对象,用于处理消息
Handler handler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        
        // 根据消息类型进行相应的处理
        if (msg.what == UPDATE_UI) {
            // 更新 UI 中的文本框内容
            textView.setText((String) msg.obj);
        }
    }
};

在上面的例子中,我们首先创建了一个新的线程(backgroundThread),用于执行耗时任务。在任务执行完成后,我们创建了一个消息对象(message),并通过 Handler 发送到主线程的消息队列中。主线程中的 Handler 负责处理收到的消息,根据消息类型进行相应的处理,例如更新 UI 中的文本框内容。

四、补充说明

每个 Handler 都会与一个特定的消息队列相关联,并且可以通过该消息队列来接收和处理消息。这意味着,在一个线程中可以有多个 Handler 对象,它们可以处理来自消息队列的消息,执行各种任务。多个子线程的Handler都可以向主线程的Handler发送消息,这些消息都会存放在主线程的消息队列中。当主线程的 Looper 循环从消息队列中获取消息时,它会依次处理这些消息,并调用相应的 Handler 来处理消息。主线程的 Handler 必须在主线程中创建,并关联主线程的 Looper 对象,以确保能够正确地处理主线程的消息队列中的消息。

五、实际开发中的一个简单应用

需要弹出连续两个Toast消息时,后一个会把前一个覆盖,可以使用Handler解决。

handler.post(() -> {
    Toast.makeText(context, "Text1", Toast.LENGTH_LONG).show();
    handler.postDelayed(() -> Toast.makeText(context, "Text2", Toast.LENGTH_LONG).show(), Toast.LENGTH_SHORT + 500);
});

语法解析:使用post()方法和Lambda表达式,将一个Runable对象投递给与此handler关联的消息队列,等待消息队列中的消息被 Looper 循环取出并交给 Handler 处理,然后执行其中操作。Runable对象中定义了两个Toast操作,并使用了postDelayed()方法将第二个Toast延迟执行,延迟时间为Toast.LENGTH_SHORT + 500ms。

整个代码块的执行逻辑是:先将一个任务(显示 Text1" 的 Toast)投递到消息队列中,然后在 Toast.LENGTH_SHORT + 500 毫秒后,再将另一个任务(显示 "Text2" 的 Toast)投递到消息队列中。这两个任务会在消息队列中依次执行,而不是并行执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值