Handler 知识点梳理:Handler、Looper 以及 Message 三者之间的关系

56 篇文章 12 订阅
订阅专栏
49 篇文章 1 订阅
订阅专栏
43 篇文章 0 订阅
订阅专栏

前言

Handler、Looper以及Message之间的关系,概括性来说,Looper负责的是创建一个MessageQueue对象,然后进入到一个无限循环体中不断取出消息,而这些消息都是由一个或者多个Handler进行创建处理

Messagequeue 的数据结构是什么

基础数据结构中 “先进先出” 的一种数据结构

Handler post 原理

消息是通过 MessageQueen 中的 enqueueMessage()方法加入消息队列中的,并且它在放入中就进行好排序,链表头的延迟时间小,尾部延迟时间最大

  • Looper.loop()通过 MessageQueue 中的 next()取消息
  • next()中如果当前链表头部消息是延迟消息,则根据延迟时间进行消息队列会 阻塞,不返回给 Looper message,知道时间到了,返回给 message
  • 如果在阻塞中有新的消息插入到链表头部则唤醒线程
  • Looper 将新消息交给回调给 handler 中的 handleMessage 后,继续调用 MessageQueen的next()方法,如果刚刚的延迟消息还是时间未到,则计算时间继续阻塞

handler.postDelay()的实现是通过MessageQueue中执行时间顺序排列,消息队列阻塞和唤醒的方式结合实现的;如果真的是通过延迟将消息放入到 MessageQueen中,那放入多个延迟消息就要维护多个定时器

Android 消息机制的简介

在 Android 中使用消息机制,我们首先想到的就是 Handler;没错,Handler是 Android 消息机制的上层接口;Handler 的使用过程很简单,通过它可以轻松地将一个任务切换到Handler所在的线程中去执行。通常情况下,Handler的使用场景就是更新UI

在子线程中,进行耗时操作,执行完操作后,发送消息,通知主线程更新 UI;这便是消息机制的典型应用场景。我们通常只会接触到 Handler 和 Message 来完 成消息机制,其实内部还有两大助手来共同完成消息传递

消息机制的模型 消息机制主要包含: MessageQueue,Handler和Looper这三大部分,以及Message,下面我们一一介绍

  • Message: 需要传递的消息,可以传递数据;
  • MessageQueue: 消息队列,但是它的内部实现并不是用的队列,实际上是通过 一个单链表的数据结构来维护消息列表,因为单链表在插入和删除上比较有优 势。主要功能向消息池投递消息(MessageQueue.enqueueMessage)和取走消息池的消息(MessageQueue.next);
  • Handler: 消息辅助类,主要功能向消息池发送各种消息事件 (Handler.sendMessage)和处理相应消息事件(Handler.handleMessage);
  • Looper: 不断循环执行(Looper.loop),从 MessageQueue中读取消息,按分发机制将消息分发给目标处理者
消息机制的架构

消息机制的运行流程: 在子线程执行完耗时操作,当 Handler 发送消息时,将会 调用MessageQueue.enqueueMessage,向消息队列中添加消息

当通过Looper.loop 开启循环后,会不断地从线程池中读取消息 ,即调用 MessageQueue.next,然后 调用目标 Handler(即发送该消息的 Handler)的 dispatchMessage 方法传递消息,然后返回到 Handler 所在线程,目标 Handler 收到消息,调用 handleMessage方法,接收消息,处理消息

MessageQueue,Handler 和 Looper 三者之间的关系: 每个线程中只能存在一个 Looper,Looper 是保存在 ThreadLocal 中的。主线程(UI 线程)已经创建了一个 Looper,所以在主线程中不需要再创建 Looper,但是在其他线程中需要创建 Looper

每个线程中可以有多个 Handler,即一个Looper 可以处理来自多个 Handler的消息 ;Looper 中维护一个MessageQueue,来维护消息队列,消息队列中的 Message可以来自不同的 Handler

  • Looper 有一个 MessageQueue 消息队列
  • MessageQueue 有一组待处理的 Message
  • Message中记录发送和处理消息的 Handler
  • Handler中有 Looper 和 MessageQueue

我们可以使用 Handler 发送并处理与一个线程关联的 Message 和 Runnable ;(注意:Runnable 会被封装进一个 Message,所以它本质上还是一个 Message ) 每个 Handler 都会跟一个线程绑定,并与该线程的 MessageQueue 关联在一起, 从而实现消息的管理以及线程间通信

  • Handler 的背后有着 Looper 以及 MessageQueue 的协助,三者通力合作,分工 明确;尝试小结一下它们的职责,如下:
  • Looper : 负责关联线程以及消息的分发在该线程下从 MessageQueue 获取 Message,分发给 Handler ;
  • MessageQueue : 是个队列,负责消息的存储与管理,负责管理由 Handler 发送过 来的 Message ;
  • Handler : 负责发送并处理消息,面向开发者,提供 API,并隐藏背后实现的细节
    Handler 发送的消息由 MessageQueue 存储管理,并由 Loopler 负责回调消息 到 handleMessage();线程的转换由 Looper 完成,handleMessage() 所在线程由 Looper.loop() 调用 者所在线程决定

Handler 引起的内存泄露原因以及最佳解决方案

Handler 允许我们发送延时消息,如果在延时期间用户关闭了 Activity,那么该 Activity 会泄露

这个泄露是因为 Message 会持有 Handler,而又因为 Java 的特性,内部类会 持有外部类,使得 Activity 会被 Handler 持有,这样最终就导致 Activity 泄露

解决该问题的最有效的方法是:将 Handler 定义成静态的内部类,在内部持有 Activity 的弱引用,并及时移除所有消息

示例代码如下:

private static class SafeHandler extends Handler {
private WeakReference<HandlerActivity> ref;
public SafeHandler(HandlerActivity activity) {
this.ref = new WeakReference(activity);
}
@Override
public void handleMessage(final Message msg) {
HandlerActivity activity = ref.get();
if (activity != null) {activity.handleMessage(msg);
}
}}

并且再在 Activity.onDestroy() 前移除消息,加一层保障:

@Overrideprotected void onDestroy() {
safeHandler.removeCallbacksAndMessages(null);
super.onDestroy();
}

这样双重保障,就能完全避免内存泄露了。注意:单纯的在 onDestroy 移除消息并不保险,因为 onDestroy 并不一定执行

    1. Handler 的 背 后 有 Looper 、 MessageQueue 支 撑 , Looper 负 责 消 息 分 发 , MessageQueue 负责消息管理;
    1. 在创建 Handler 之前一定需要先创建 Looper;
    1. Looper 有退出的功能,但是主线程的 Looper 不允许退出;
    1. 异步线程的 Looper 需要自己调用 Looper.myLooper().quit(); 退出;
    1. Runnable 被封装进了 Message,可以说是一个特殊的 Message;
    1. Handler.handleMessage() 所在的线程是 Looper.loop() 方法被调用的线程,也可以说成 Looper所在的线程,并不是创建Handler的线程;
    1. 使用内部类的方式使用Handler可能会导致内存泄露,即便在 Activity.onDestroy 里移除延时消息,必须要写成静态内部类

Android UI 是线程不安全的,如果在子线程中尝试进行 UI 操作,程序就有可能 会崩溃

相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也 是早已烂熟于心,即创建一个 Message 对象,然后借助 Handler 发送出去,之 后在 Handler 的 handleMessage()方法中获得刚才发送的 Message 对象,然 后在这里进行 UI 操作就不会再出现崩溃了

在主线程中可 以直接创建 Handler 对象,而在子线程中需要先调用 Looper.prepare()才能创 建 Handler 对象

有关 Handler 的知识点就到这里了, 有需要学习更多关于 Handle 知识点的同学,可以 私信 发送 “进阶” 即可 获取一份 学习笔记 ,相信能够帮助大家 查漏补缺

资料部分内容展示如下:

《Handler 机制之 Thread》

  • 线程概念
  • Android线程的实现
  • 线程的阻塞
  • 关于线程上下文切换
  • 关于线程的安全问题
  • 守护线程
  • 线程的内存

《Handler机制之ThreadLocal》

  • Java中的ThreadLocal
  • ThreadLocal的前世今生
  • Android中的ThreadLocal
  • Android 面试中的关于ThreadLocal的问题
  • ThreadLocal的结构
  • ThreadLocal静态类ThreadLocal.Values
  • ThreadLocal的总结

完整版PDF文档获取方式: 私信 发送 “进阶” 即可 免费获取

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

Android 架构师之路还很漫长,与君共勉

Handler Looper Message 关系是什么?
陈立的博客
10-27 672
分析 Handler 首先我们来分析分析一下 Handler 的用法,我们知道,要创建一个 Handler 对象非常的简单明了,直接进行 new 一个对象即可,但是你有没有想过,这里会隐藏着什么注意点呢。现在可以试着写一下下面的一小段代码,然后自己运行看看: public class MainActivity extends ActionBarActivity { private Handler mHandler0; private Handler mHandler1; .
AndroidHandlerMessageMessageQueue、Looper详解
最新发布
是阿超
12-06 2843
AndroidHandlerMessageMessageQueue、Looper详解
Android LooperHandler
Hknock的专栏
05-29 1438
Android中的Looper , Handler , Message Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。 Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessag
handler和looper关系
Tianhui Yang的个人网站:aitech.me
05-16 651
Android应用启动时,会默认有一个主线程(UI线程),在这个线程中会关联一个消息队列,所有的操作都会被封装成消息然后交给主线程来处理。 为了保证主线程不会主动退出,会将取消息的操作放在一个死循环中,这样程序就相当于一直在执行死循环,因此不会退出。 在应用启动时,会开启一个主线程(UI线程),并且启动消息循环,应用不停地从该消息队列中取出、处理消息达到程序运行的效果。 Looper对象封装
Android中的Handler,Looper,Message机制
weixin_30641999的博客
11-29 171
Android的消息处理有三个核心类:Looper,HandlerMessage。其实还有一个Message Queue(消息队列),但是MQ被封装到Looper里面了,我们不会直接与MQ打交道,因此我没将其作为核心类。下面一一介绍:线程的魔法师 LooperLooper的字面意思是“循环者”,它被设计用来使一个普通线程变成Looper线程。所谓Looper线程就是循环工作的线程。在程序开发...
Handler、LooperMessage之间关系
baidu_39503346的博客
03-21 590
Handler、Looper(轮循器)、MessageQueue(消息队列)、Message(消息)工作原理----面试问题 与Handler一起工作的几个组件: MessageHandler接收和处理的消息对象。 MessageQueue:消息队列,他采用先进先出的方式来管理MessageHandler发送消息时先把消息发送到消息队列中。 Looper:每个线...
深度解析Android消息机制:Handler、LooperMessage
本资源详细介绍了这些概念及其工作原理,同时也涉及了相关知识点的延伸。 1. **Handler**:Handler是用于发送和处理消息的核心类。开发者可以创建一个Handler实例,然后通过它的`sendMessage()`方法发送消息,或者...
Android 消息机制:HandlerMessageQueue 和 Looper
你好,开发者
11-04 1328
在这篇文章中,我们将会讨论 Android 的消息机制。提到 Handler,有过一些 Android 开发经验的都应该很清楚它的作用,通常我们使用它来通知主线程更新 UI。但是 Handler 需要底层的 MessageQueue 和 Looper 来支持才能运作。这篇文章中,我们将会讨论它们三个之间关系以及实现原理。 在这篇文章中,因为涉及线程方面的东西,所以就避不开 ThreadLocal...
Handler、LooperMessageQueue知识点及工作原理简单介绍
qq_34696209的博客
06-20 391
文章目录子线程更新UI的几种方法子线程使用Handler和Looper为什么必须调用Looper.prepare()/Looper.loop()Handler/Looper/MessageQueue之间关系1、为什么Android主线程可以直接创建Handler2、为什么在Activity中使用匿名内部类创建Handler会导致内存泄漏HandlerThread1、HandlerThread的简单使用2、HandlerThread原理分析 子线程更新UI的几种方法 1、使用Handler 2、Ac
安卓高级面试指南:Handler与Looper深度解析
2. Looper(循环器):Looper是消息队列的管理者,它在一个线程中不断循环地从消息队列中取出Message并分发给相应的Handler去处理。在主线程中,Looper已经默认启动;而在子线程中,需要手动调用Looper.prepare()...
Handler/Looper/Message关系
LSLSD的博客
07-28 214
Handle:封装了消息的发送,也负责接收消息。内部与Looper相关联 Looper:封装消息的载体,内部包含了MessgerQueue,负责从MessageQueue中获取消息,把消息传递给Handler处理 MessageQueue:消息队列,负责存储消息,有消息过来就存储起来,Looper会循环的从MessageQueue中读取消息 ...
HandlerMessage和Looper之间关系
nxc_boy的博客
10-21 1276
一、研究背景         在学习Android的多线程编程中,发现Android中规定UI的更新只能在主线程中进行,在子线程中是禁止的,但是主线程又不能进行耗时操作。为了解决既能更新UI又能进行耗时操作的需求,从而出现了消息机制、AsyncTask异步任务这两种方式。 二、Android的消息机制         在Android的消息机制中会涉及到Message类、Handler类、L...
JAVAHandler 、 LooperMessage关系
weixin_40721097的博客
07-03 336
Handler 、 LooperMessage三者都与Android异步消息处理线程相关的概念。 异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环。若消息队列为空,线程则会阻塞等待。 Handler 、 LooperMessage关系其实是:Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息,而消息的创建者就是...
handler与looper关系HandlerThread
weixin_30247159的博客
07-12 97
handler与looper关系HandlerThread 做了也快2年的android了,发现android的机制还不是很了解,这几天看了一下这方面的介绍,总结一下handler的用法和机制。 handler就是用来线程之间通信的,主线程与子线程。一般的用法是,子线程通知ui主线程的handler去刷新ui操作。最近遇到一些人,问...
Androidhandler , looper 以及 message关系
静祥阁
11-17 1376
声明: 在我的工作中用到了handler,looper 以及 message关系,所以我在这里总结一下自己对他们关系的了解,同时也会在后面介绍如何使用他们来完成自己的任务。同时还是强调,这是我自己的一些工作总结,可能有不完善的地方, 请大家指正,希望对你有所帮忙。同时这里面有很多的looperhandler,以及message等,其实他们的首字母是大写的,只是我这里为了方便就使用小...
Handler Looper Message 关系是什么?【整理】
wodexiaochengxu的博客
08-03 121
本系列文章在 https://github.com/mzlogin/rtfsc-android 持(jing)续(chang)更(duan)新(geng)中,欢迎有兴趣的童鞋们关注。Android 源码分析 —— Handler、LooperMessageQueue — 码志。
Android开发Handler和Looper关系
weixin_33743703的博客
10-03 89
          关于Handler的总结。 Message:消息,当中包括了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。 Handler:处理者,负责Message的发送及处理。使用Handler时,须要实现handleMessage(Message msg)方法来对特定的Message进行处理,比如更新UI等。 ...
LooperHandlerMessage三者关系
HUandroid的博客
03-06 407
LooperHandlerMessage关系,一般面试的必答题,涉及到Android的异步消息处理机制。 简单的来说,我们一般用Handler实现异步消息处理。为什么会用到Handler? 子线程不允许访问 UI(在多线程情况下,UI控件会处于不可预期的状态) Handler采用单线程模型,切换到UI线程去操作UI,解决以上问题。
Handler与Looper关系
u012143388的专栏
03-11 330
源:http://blog.csdn.net/illusion_luna/article/details/8222657 先来看一下Looper这个类: 再来看一下handler这个类的google给出的解释: 简单的来说:大家可以这样来理解,有一个消息队列MessageQueue(队列应该大家都知道了吧。。。。。),我们handler要做的工作就是将
写文章

热门文章

  • Android开发中的NDK到底是什么?(详细解析+案例) 17418
  • Android 中的 NDK 到底是什么?(详细解析+案例实战) 9601
  • 鸿蒙开发实战:网络请求库【axios】 6559
  • Anroid组件化构架设计 5533
  • 鸿蒙开发实战-OpenHarmony沙箱文件 4053

分类专栏

  • 鸿蒙开发 244篇
  • Android开发 56篇
  • Android Jetpack 4篇
  • Flutter 3篇
  • 架构师 3篇
  • Android 性能优化 4篇
  • 音视频开发 6篇
  • Android逆向开发 2篇
  • 面试、 1篇
  • 车机开发
  • Android工程师 43篇
  • UI
  • 11
  • Android Framework 4篇
  • 音视频 2篇
  • 面试
  • 移动开发 49篇
  • 实时音视频 2篇

最新评论

  • 鸿蒙实战开发:【7日天气预报】

    2401_84412167: 同学你拿到源码了吗

  • 鸿蒙实战开发:【7日天气预报】

    2401_84412167: 同学你拿到源码了吗

  • 鸿蒙开发实战:网络请求库【axios】

    追风少年+1: 文章介绍了适配OpenHarmony的Axios库,保留原版1.3.4的特性和用法,支持HTTP请求、Promise API、拦截器和JSON自动转换。提供的参考资料丰富,适合初学者和开发者深入了解和使用Axios。

  • 鸿蒙开源!OpenHarmony——手机的CPU信息应用

    epubcn: CPU_device_information 连接 404 了

  • HarmonyOS开发:【NFC配置流程】

    ༺ 。. ༻: 请问一下现在HarmonyOS服务开发平台这个板块好像不见了,还能有别的方法来配置吗

最新文章

  • 鸿蒙ArkTS声明式开发:跨平台支持列表【图形变换】 通用属性
  • 鸿蒙ArkTS声明式开发:跨平台支持列表【Z序控制】 通用属性
  • 鸿蒙ArkTS声明式开发:跨平台支持列表【浮层】 通用属性
2024
06月 4篇
05月 72篇
04月 78篇
03月 46篇
02月 14篇
01月 25篇
2023年18篇
2022年98篇
2021年11篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

玻璃钢生产厂家玻璃钢广场卡通雕塑定制徐州玻璃钢花盆丽江玻璃钢雕塑批发零售梁园玻璃钢雕塑设计烟台户外玻璃钢雕塑造型浙江玻璃钢卡通雕塑草莓玻璃钢雕塑假山石商场开业美陈注意事项玻璃钢雕塑壁纸可爱玻璃钢美人鱼雕塑图片南京韶关玻璃钢动物雕塑玻璃钢雕塑哪家最好邯郸玻璃钢花盆花器江苏玻璃钢雕塑加工厂大屯商场美陈玻璃钢雕塑收费标准西安玻璃钢雕塑加工厂家福建秋季商场美陈销售企业中山哪家公司有玻璃钢雕塑山东仿真蔬菜玻璃钢雕塑湖南大型玻璃钢雕塑厂家湖北景观园林玻璃钢彩绘雕塑上海主题商场美陈价格无锡十一商场美陈广东户外商场美陈多少钱四川高质量玻璃钢雕塑图片阳江玻璃钢卡通猪雕塑江苏玻璃钢天使人物雕塑厂家北京玻璃钢花盆制造玉溪玻璃钢雕塑批发商香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化