深入理解Android消息机制的原理

Handler & Looper & MessageQueue关系简述

  • 一个线程至多有一个looper;一个looper有一个mq;一个mq对应多个message;一个message对应多个handler。
  • 消息类型:同步、异步、同步屏障消息。
  • 无限循环:在队列中没有消息时,当前线程进入阻塞状态,当有消息进来时才唤醒该线程,因此不会占用cpu的资源。
    在这里插入图片描述

消息分发的优先级:

  1. Message的回调方法:message.callback.run(),优先级最高
  2. Handler的回调方法:Handler.mCallback.handleMessage(msg)
  3. Handler的默认方法:Handler.handleMessage(msg)
        //1.直接在runnable中处理任务handler.post {}//2.使用Handler.Callback来处理消息val handler:Handler = object :Handler(Callback {return@Callback true})//3.使用handleMessage处理消息val handler = object :Handler(){override fun handleMessage(msg: Message) {super.handleMessage(msg)}}
  • 为什么主线程中创建Handler没有绑定looper,也能发送消息呢?

    • 在ActivityTread.main()方法中调用了Looper.prepareMainLooper()方法创建了主线程的Looper,然后调用了loop()开启消息队列轮询
    • 通常我们认为ActivityTread就是主线程,实际上它并不是一个线程,而是主线程操作的管理者
class Looper{//相当于map,key时线程,value是looperstatic final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();//一个线程只能有一个Looper,prepare不能重复声明private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper(quitAllowed));}public static @Nullable Looper myLooper() {//获取当前线程的looperreturn sThreadLocal.get();}}

在这里插入图片描述

//使用post方法消息入队,最后会把runnable包装成一个messagepublic final boolean post(@NonNull Runnable r) {return  sendMessageDelayed(getPostMessage(r), 0);}private static Message getPostMessage(Runnable r) {Message m = Message.obtain();m.callback = r;return m;}//使用享元设计模式,提高内存的利用率public static Message obtain() {synchronized (sPoolSync) {if (sPool != null) {Message m = sPool;sPool = m.next;m.next = null;m.flags = 0; // clear in-use flagsPoolSize--;return m;}}return new Message();}//当消息使用完,都会调用这个方法回收消息void recycleUnchecked() {// Mark the message as in use while it remains in the recycled object pool.// Clear out all other details.flags = FLAG_IN_USE;what = 0;arg1 = 0;arg2 = 0;obj = null;replyTo = null;sendingUid = UID_NONE;workSourceUid = UID_NONE;when = 0;target = null;callback = null;data = null;synchronized (sPoolSync) {if (sPoolSize < MAX_POOL_SIZE) {next = sPool;sPool = this;sPoolSize++;}}}

消息入队,最后都会调用到enqueueMessage方法中,enqueueMessage方法的执行逻辑分为两个部分:

1. 如果新消息的被执行时间when比队列中任何一个消息都早,则插入队头,唤醒Looper。
2. 如果当前队头是同步屏障消息,并且新消息是异步消息,则唤醒Looper。
  • postSyncBarrier同步屏障消息(该方法无法被开发者调用)

    • message.target=null,这类消息不会被真的执行,它起到了flag标记的作用,mq在遍历消息队列时,如果队头是同步屏障消息,那么会忽略同步消息,优先让异步消息得到执行。这就是它的目的,一般异步消息和同步消息会一同使用。

    • 异步消息&同步屏障 使用场景

      • ViewRootImpl接收屏幕垂直同步消息事件用于驱动UI绘制
      • ActivityThread接收AMS的事件驱动生命周期
      • InputMethodManager分发软键盘输入事件
      • PhoneWindowManager分发电话页面各种事件
  • 消息分发
    消息分发核心方法在于loop方法,loop方法里面会的调用的linux里的epoll机制。handler最终都是调到adk(c/c++)层。epoll会把哪个流发生了怎样的I/O事件通知我们。此时我们对这些流的操作都是有意义的。

ThreadLocal

  • ThreadLocal提供了线程独有的局部变量存储能力,可以在整个线程存活的过程中随时取用。
  • 注意ThreadLocal没有线程安全的能力。
    在这里插入图片描述
    多个线程操作上述的local对象的usr对象,进行数据修改之后,user变量会更改。

面试经典问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/55937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32串口通信(PC--stm32;中断接收方式;附proteus电路图;开发方式:cubeMX)

单片机型号STM32F103R6: 最后实现的效果是&#xff0c;开机后PC内要求输入1或0&#xff0c;输入1则打开灯泡&#xff0c;输入0则关闭灯泡&#xff0c;输入其他内容则显示错误&#xff0c;值得注意的是这个模拟的东西只能输入英文 之所以用2个LED灯是因为LED电阻粗略一算就是1…

fat32 文件系统 误删除文件数据恢复 SDK 介绍

fat32 文件系统 误删除文件数据恢复 SDK 介绍 fat32_analyze.dll 是一个专门用于恢复 fat32 文件系统误删除文件的标准的动态链接库(DLL)&#xff0c; 可被任何其他程序直接加载调用。 下载地址&#xff1a; https://gitee.com/tankaishuai/powerful_sdks/tree/master/fat32_a…

【Tkinter系列02/5】界面初步和布局

本文是系列文章第二部分。前文见&#xff1a;【Tkinter系列01/5】界面初步和布局_无水先生的博客-CSDN博客 说明 一般来说&#xff0c;界面开发中&#xff0c;如果不是大型的软件&#xff0c;就不必用QT之类的实现&#xff0c;用Tkinter已经足够&#xff0c;然而即便是Tkinter规…

spring boot 项目整合 websocket

1.业务背景 负责的项目有一个搜索功能&#xff0c;搜索的范围几乎是全表扫&#xff0c;且数据源类型贼多。目前对搜索的数据量量级未知&#xff0c;但肯定不会太少&#xff0c;不仅需要搜索还得点击下载文件。 关于搜索这块类型 众多&#xff0c;未了避免有个别极大数据源影响整…

linux操作系统的权限的深入学习(未完)

1.Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的命令提示符是“#”&#xff0c;普通用户…

Spring Authorization Server入门 (十六) Spring Cloud Gateway对接认证服务

前言 之前虽然单独讲过Security Client和Resource Server的对接&#xff0c;但是都是基于Spring webmvc的&#xff0c;Gateway这种非阻塞式的网关是基于webflux的&#xff0c;对于集成Security相关内容略有不同&#xff0c;且涉及到代理其它微服务&#xff0c;所以会稍微比较麻…

Prometheus 监控系统

常用的监控系统有哪些&#xff1f; 老牌传统 Zabbix Nagios Cacti 新一代的 Prometheus 夜莺 Zabbix 和 Prometheus 的区别&#xff1f;如何选择&#xff1f;【重中之重】 Zabbix 更适用于传统业务架构的物理机、虚拟机环境的监控&#xff0c;对容器环境的支持较差&#xf…

战略形成是权力妥协的过程,江湖,政治是常态

战略权力派&#xff1a;战略形成是各种权力妥协的过程【安志强趣讲270期】 趣讲大白话&#xff1a;有人的地方就有政治 **************************** 有人的地方就有江湖 有组织的地方就有政治 公司的战略是各种人的权力博弈的产物 围观权力&#xff1a;就是组织内部 宏观权力…

MyCAT命令行监控

9066端口 &#xff0c;用mysql命令行连接 Mysql –utest –ptest –P9066 show help 可显示所有相关管理命令 显示后端物理库连接信息&#xff0c;包括当前连接数&#xff0c;端口 Show backend Show connection 显示当前前端客户端连接情况&#xff0c;已经网络流量信息、…

Tomcat 部署时 war 和 war exploded区别

在 Tomcat 调试部署的时候&#xff0c;我们通常会看到有下面 2 个选项。 是选择war还是war exploded 这里首先看一下他们两个的区别&#xff1a; war 模式&#xff1a;将WEB工程以包的形式上传到服务器 &#xff1b;war exploded 模式&#xff1a;将WEB工程以当前文件夹的位置…

【Go 基础篇】Go语言数组遍历:探索多种遍历数组的方式

数组作为一种基本的数据结构&#xff0c;在Go语言中扮演着重要角色。而数组的遍历是使用数组的基础&#xff0c;它涉及到如何按顺序访问数组中的每个元素。在本文中&#xff0c;我们将深入探讨Go语言中多种数组遍历的方式&#xff0c;为你展示如何高效地处理数组数据。 前言 …

2023年高教社杯 国赛数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…

YOLO目标检测——肺炎分类数据集下载分享

肺炎分类数据集总共21000图片&#xff0c;可应用于&#xff1a;肺炎检测、疾病诊断、疾病预测和预警等等。 数据集点击下载&#xff1a;YOLO肺炎分类数据集21000图片.rar

如何深入理解 Node.js 中的流(Streams)

Node.js是一个强大的允许开发人员构建可扩展和高效的应用程序。Node.js的一个关键特性是其内置对流的支持。流是Node.js中的一个基本概念&#xff0c;它能够实现高效的数据处理&#xff0c;特别是在处理大量信息或实时处理数据时。 在本文中&#xff0c;我们将探讨Node.js中的流…

腾讯云服务器地域和可用区详细介绍_选择攻略

腾讯云服务器地域有什么区别&#xff1f;怎么选择比较好&#xff1f;地域选择就近原则&#xff0c;距离地域越近网络延迟越低&#xff0c;速度越快。关于地域的选择还有很多因素&#xff0c;地域节点选择还要考虑到网络延迟速度方面、内网连接、是否需要备案、不同地域价格因素…

微服务dubbo

微服务是一种软件开发架构风格&#xff0c;它将一个应用程序拆分成一组小型、独立的服务&#xff0c;每个服务都可以独立部署、管理和扩展。每个服务都可以通过轻量级的通信机制&#xff08;通常是 HTTP/REST 或消息队列&#xff09;相互通信。微服务架构追求高内聚、低耦合&am…

Cookie for Mac:隐私保护工具保护您的在线隐私

随着互联网的发展&#xff0c;我们每天都会浏览各种网站&#xff0c;享受在线购物、社交娱乐和学习资料等各种便利。然而&#xff0c;您是否曾经遇到过需要频繁输入用户名和密码的情况&#xff1f;或者不方便访问您常用的网站&#xff1f;如果是这样&#xff0c;那么Cookie for…

pytest

1.安装 pip install pytestpytest官网&#xff1a;https://docs.pytest.org/en/stable/ 2.编写规则 1.测试文件已test开头&#xff08;或以test结尾&#xff09; 2.测试类以Test开头&#xff0c;并且不能带有init方法 3.测试函数以test开头 4.断言使用基本的assert即可 3.p…

基于树莓派设计的酒店房间号智能识别系统(图像识别)

基于树莓派4B设计的酒店房间号智能识别系统(图像识别) 一、设计需求 酒店房间识别系统的主要目的是:通过图像处理技术,以机器视觉的方式识别光学传感器传回的酒店房间图像中的数字,该系统可以以非接触的方式,以图像的方式获得需要的酒店房间读数,这能极大提高老式的酒店房…

Matlab图像处理-乘法运算

乘法运算 两幅图像进行乘法运算主要实现两个功能&#xff1a; 一是可以实现掩模操作&#xff0c;即屏蔽图像的某些部分&#xff1b; 二是如果一幅图像乘以一个常数因子&#xff0c;如果常数因子大于1&#xff0c;将增强图像的亮度&#xff0c;如果因子小于1则会使图像变暗。…