引子

项目进度慢下来,终于有时间可以温故知新。

消息机制,贯穿Android系统的 事件传递机制,包含1个主角Handler,3个配角 ThreadLocal,MessageQueue,Looper,本文将详述4个东西之间的关系,大概这就是消息机制的原理了吧。

关键词

Handler,ActivityThread,ThreadLocal,MessageQueue,Looper ···

主角 - Handler

正确的说法是:Handler的作用,是切换任务执行的线程 (理论上,可以切换到任意线程,比如,切到子线程)。

而由于android更新UI只能在主线程,所以,我们平时用handler就是通知主线程更新UI,如果强行让子线程去更新UI,则会报出异常:Only the original thrad that created a view hierarchy can touch its view(只有创建View的线程可以解除它的view。主线程创建View)

事实上,主线程,子线程,在本质上都一样,只是android里面对主线程做了详细设定,让它只能更新UI,不能进行耗时操作(如果耗时操作持续一定时间,大概5秒,系统就会判定程序已经死了,报出ANR异常)。

发散一下:

1、为何谷歌不让子线程去更新UI,因为android的UI控件并不是线程安全的,这就意味着,并发操作将会引发不可控的结果。

2、为何不把控件做成线程安全的呢?因为要做做成线程安全,就要对更新控件的函数进行加锁,加锁有缺点,一是让UI访问变得复杂,二是,降低UI的访问效率。所以,与其加锁,还不如干脆让 默认的一个主线程来执行所有的UI操作。

配角1号 ThreadLocal

乍一看,这个难道是一个线程的派生类?NO,它和线程有关,但是并不是线程。

ThreadLocal的作用是:以线程对象为作用域,进行数据存储

什么意思? 就是,它类似(但是并不等同)一个Map映射,以线程对象为key,来进行 数据存储。

举个例子: 如果你有个需求,同时开启多个线程进行文件下载,而你需要在每个线程中都存一个独立的“下载进度”,要保证他们互不干涉。这个就符合ThreadLocal的使用场景,直接使用它就行了,当然你也可以用其他方式,这里只是举例说明。

Android中消息机制,ThreadLocal被用来 存Looper对象,让每个线程的Looper对象相互独立

想看源码的,请移步Looper.java,搜索ThreadLocal...

ThreadLocal构造函数中有一个泛型,这里指定了Looper作为存储类型

配角2号 MessageQueue

MessageQueue,消息的容器。

看上去是一个Queue,队列?NO,谷歌的大佬们也会玩障眼法。其实,MessageQueue的数据结构是:单链表,为什么用单链表?因为单链表在 数据的插入和删除方面要优于队列。

直接找到MessageQueue.java 源码,可以找到它的2个关键方法:

1、enqueueMessage() 消息入列

参数1,就是msg消息对象。

它的作用,就是将msg对象插入到单链表中。

2、next()获取消息

返回值是消息对象。

分析源码得出,

它是用一个无限for循环 ,获取一个Message,如果获取不到,就会一直循环,阻塞在这里,直到有 消息,就把消息返回出去,并且把这个消息从单链表中删除。

配角3号 Looper

Looper 消息循环

关键方法:

用于当前线程中创建一个Looper对象,这是个静态方法,只需要调用Looper.prepare().它会自动创建本线程的Looper对象,然而,最多创建一个,多次创建会报异常。

用于启动当前线程Looper的消息循环(进入源码能看到,没错,又是无限for循环···)

无限循环,检查MessageQueue中有没有新的消息,如果有,就调用msg.target.dispatchMessage(msg),如果没有,就被queue.next()阻塞了。除非next返回null(什么时候会返回空?结论是消息队列被标记为推出状态时,会返回空)

角色关系

OK,角色介绍完了,那么他们之间怎么发生作用,共同构成Android的消息机制呢?

看图;

图画得吃藕,不要在意这些细节,大概意思就是这样。

4个角色都是在同样一个作用域下进行的,如果这个线程是主线程,那么Thread就是 ActivityThread(主线程,没错,主线程的类,就是它)

解释一下:

ThreadLocal负责存储当前线程的Looper对象。

Looper负责对MessageQueue进行循环

MessageQueue负责对msg进行暂时存储,并且在next出了 msg之后,调用dispatchMessage告诉handler执行消息

Handler创建的时候,需要Looper作为参数,它提供sendMessage/post方法供外界调用;

以上就是我们一个Thread作用域下的消息机制全图。

结语

学而时习之,不亦乐呼。温故而知新,可以为师矣。常总结,常进步。

共勉!

转载于:https://www.cnblogs.com/hankzhouAndroid/p/9720150.html

Android-消息机制总结相关推荐

  1. Android消息机制Handler用法

    这篇文章介绍了Android消息机制Handler用法总结,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 1.简述 Handler消息机制主要包括: Messa ...

  2. 【腾讯Bugly干货分享】经典随机Crash之二:Android消息机制

    为什么80%的码农都做不了架构师?>>>    本文作者:鲁可--腾讯SNG专项测试组 测试工程师 背景 承上经典随机Crash之一:线程安全 问题的模型 好几次灰度top1.top ...

  3. android消息池,回转寿司你一定吃过!——Android消息机制(构造)

    消息机制的故事寿司陈放在寿司碟上,寿司碟按先后顺序被排成队列送上传送带.传送带被启动后,寿司挨个呈现到你面前,你有三种享用寿司的方法. 将Android概念带入后,就变成了Android消息机制的故事 ...

  4. android handler的机制和原理_一文搞懂handler:彻底明白Android消息机制的原理及源码

    提起Android消息机制,想必都不陌生.其中包含三个部分:Handler,MessageQueue以及Looper,三者共同协作,完成消息机制的运行.本篇文章将由浅入深解析Android消息机制的运 ...

  5. Android 消息机制详解(Android P)

    前言 Android 消息机制,一直都是 Android 应用框架层非常重要的一部分,想更加优雅的进行 Android 开发,我想了解消息机制是非常必要的一个过程,此前也分析过很多次 Handler ...

  6. Android消息机制基本原理和使用

    在Android开发过程中,我们常常遇到子线程更新UI的需求,例如在子线程进行耗时较长的下载,等下载完成之后,再去更新UI,提示用户下载完成,直接在子线程里更新UI,会得到报错提示:Only the ...

  7. 理解 Android 消息机制

    本人只是Android小菜一个,写技术文章只是为了总结自己最近学习到的知识,从来不敢为人师,如果里面有不正确的地方请大家尽情指出,谢谢! 本文基于原生 Android 9.0 源码来解析 Androi ...

  8. Android 系统(177)---Android消息机制分析:Handler、Looper、MessageQueue源码分析

    Android消息机制分析:Handler.Looper.MessageQueue源码分析 1.前言 关于Handler消息机制的博客实际上是非常多的了. 之前也是看别人的博客过来的,但是过了一段时间 ...

  9. Android 消息机制(Handler运行机制)

     1 Android 消息机制 Android 的消息机制主要是指Handler的运行机制,Handler的运行需要底层的MessageQueue和Looper的支撑 2 为什么要用Handler消息 ...

  10. Android消息机制(Handler机制) - 线程的等待和唤醒

    我们都知道,Android的Handler机制,会在线程中开启消息循环,不断的从消息队列中取出消息,这个机制保证了主线程能够及时的接收和处理消息. 通常在消息队列中(MessageQueue)中没有消 ...

最新文章

  1. php读取access编码格式,php+access如何设置编码格式
  2. SAP S4HANA MRP LIVE
  3. JAVA中int、String的类型转换
  4. table合并单元格宽度自适应
  5. 某道词典在线翻译JS解密,完全扣js代码解密 (小白基础篇)
  6. 混合app用百分比还是rem_[笔记]em, rem最佳实践
  7. 【Oracle】Rman简介
  8. 北大光华管理学院教授:互联网未来会如何影响经济社会的发展?
  9. lbp特征的matlab实现
  10. 汉编国有资产综合管理系统简介
  11. 使用腾讯云文字识别提取图片中的文字内容
  12. java验证图片大小_java 校验图片的大小、尺寸、比例
  13. HRBUST1313-火影忍者之~静音
  14. 计算智能——粒子群优化算法实验
  15. 压力测试-Jmeter测试移动APP
  16. 固定资产管理系统如何简化固定资产管理和盘点工作?
  17. 是时候复习一下响应式设计了
  18. 曼尼托巴大学计算机科学硕士,曼尼托巴大学计算机科学本科申请.pdf
  19. 困惑与破题:人人喊打的屏幕时间究竟对孩子做了什么?
  20. 主板电源开关接口图解_电脑主板上的电源开关插头怎么接啊

热门文章

  1. json中含有Unicode的处理办法 C#
  2. Java Applet编程总结
  3. 黑客高手是这样上网的!Vimer是如何用快捷键浏览网页的?
  4. Spring与Quartz集成详解
  5. 简短—揭开数学学科对于计算机应用的神秘面纱
  6. 15款免费IDE,推荐给开发者
  7. dos批处理命令详解(转)
  8. 杭州python爬虫招聘_python爬取招聘网站(智联,拉钩,Boss直聘)
  9. go 写文件_Pythonista 的 Go 之旅
  10. Python机器学习:评价分类结果003实现混淆矩阵,精准率和召回率