Android之Handler、Message、MessageQueue、Looper详解

Handler

Handler的原理

Handler的原理:
Android中主线程是不能进行耗时操作的,子线程是不能进行更新UI的。所以就有了Handler,它的作用就是实现线程之间的通信。


Handler整个流程中,主要有四个对象,handler,Message,MessageQueue,Looper。当应用创建的时候,就会在主线程中创建handler对象,我们通过要传送的消息保存到Message中,handler通过调用sendMessage方法将Message发送到MessageQueue中,Looper对象就会不断的调用loop()方法 不断的从MessageQueue中取出Message交给handler进行处理。从而实现线程之间的通信。

线程间通信的实现步骤

线程间通信的实现步骤:

  1. 在主线程中定义Handler的子类
  2. 重写Handler类的handleMessage()方法
  3. 用该子类定义全局的Handler对象,以便子线程使用
  4. 子线程获得handler对象用该对象的sendMessage()方法发送消息

Handler的应用场景

Handler在Android开发中有多种应用场景,以下是几种常见的使用情况:

  • 子线程通知主线程更新UI:
    Android规定只能在主线程(也称UI线程)中对界面元素进行操作。当需要在后台线程中执行耗时任务(如网络请求、数据库查询、大量计算等)后更新UI时,可以使用Handler来发送消息或Runnable到主线程,确保在主线程中正确、安全地更新界面。
  • 延迟任务或定时任务:
    Handler提供了postDelayed(Runnable, long)和sendMessageDelayed(Message, long)等方法,可以安排一个任务在未来某个时间点执行。这种机制适用于实现倒计时、动画帧刷新、定期状态检查、登录超时提醒等功能。
  • 处理下载或加载进度:
    在进行文件下载、大图加载等涉及进度变化的操作时,后台线程可以通过Handler不断发送进度更新消息到主线程,以便在界面上实时显示进度条或其他进度反馈。
  • 事件总线(Event Bus)机制:
    在复杂的应用中,Handler可以作为轻量级的事件传递机制,不同组件通过发送消息到共享的Handler来实现跨组件通信。尽管有专门的事件总线库(如 Otto、EventBus)更为高效和便捷,但Handler也能满足简单的事件发布与订阅需求。
  • 协同多个线程间的任务序列:
    当需要在多个线程间按特定顺序执行一系列任务时,Handler可以用来协调这些任务的调度。例如,一个线程完成部分工作后,通过Handler发送消息触发下一个线程开始执行,以此保证任务按照预期流程进行。
  • 响应系统事件:
    Handler可以注册接收系统级别的消息,如系统时间变更、设备方向改变等。通过重写handleMessage()方法并检查消息类型,可以对这些事件做出相应处理。

总的来说,当遇到以下需求时,可以考虑使用Handler:

  • 跨线程通信,特别是从子线程向主线程发送消息或指令。
  • 需要延迟执行的任务,无论是单次的延迟执行还是周期性的定时任务。
  • 涉及UI更新的操作,特别是在后台任务完成后需要更新界面的状态。
  • 实现简单的事件驱动编程模型,在不同组件或模块之间传递事件消息。
  • 响应特定的系统事件,在收到特定系统消息时执行特定逻辑。
  • 只要涉及到线程间消息传递、任务调度或UI更新控制,尤其是需要遵循Android主线程更新规则的情况,Handler都是一个有效的工具。

Handler在多线程中的应用

  1. 发送消息,在不同的线程间发送消息,使用的方法为sendXXX();。
    android.os.Handler对象通过下面的方法发送消息的:
    • sendEmptyMessage(int):发送一个空的消息;
    • sendMessage(Message):发送消息,消息中可以携带参数;
    • sendMessageAtTime(Message, long):未来某一时间点发送消息;
    • sendMessageDelayed(Message, long):延时Nms发送消息。
  2. 计划任务,在未来执行某任务,使用的方法为postXXX();。
    android.os.Handler对象通过下面的方法执行计划任务:
    • post(Runnable):提交计划任务马上执行;
    • postAtTime(Runnable, long):提交计划任务在未来的时间点执行;
    • postDelayed(Runnable, long):提交计划任务延时Nms执行。

如何在子线程中创建Handler

如何在子线程中创建Handler?

  1. 创建一个 HandlerThread,即创建一个包含 Looper 的线程HandlerThread 的构造函数有两个
  2. 通过 HandlerThread 的 getLooper 方法可以获取 Looper
  3. 通过 Looper 我们就可以创建子线程的 handler 了
  4. 通过该 handler 发送消息,就会在子线程执行;

如果要 handlerThread 停止: handlerThread.quit();

Hander中removeMessages方法

Hander中removeMessages方法

  1. 这个方法使用的前提是之前调用过sendEmptyMessageDelayed(0, time),意思是延迟time执行handler中msg.what=0的方法;
  2. 在延迟时间未到的前提下,执行removeMessages(0),则上面的handler中msg.what=0的方法取消执行;
  3. 在延迟时间已到,handler中msg.what=0的方法已执行,再执行removeMessages(0),不起作用。
  4. 该方法会将handler对应message队列里的消息清空,通过msg.what来找到对应的message。
  5. 当队列中没有message则handler会不工作,但并不是handler会停止,当队列中有新的message进来后,会继续处理执行。

Handler内存泄漏

Handler发生内存泄漏的情况

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是阿超

现在二师兄的肉比师父的都贵了.

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值