当前位置: 首页 > news >正文

Android Handler完全解读

一,概述

Handler在Android中比较基础,本文笔者将对此机制做一个完全解读。读者可简单参考上述类图与时序图,便于后续理解。

二,源码解读

1,主线程伊始

众所周知,通过Zygote的fork方式,新创建的子进程通过反射获取到ActivityThread的main静态方法,作为caller在Zygote中使用,

我们跟进到ActivityThread#main

调用prepareMainLooper创建主线程looper,

很简单,通过ThreadLocal保证了线程唯一,

笔者在此啰嗦下ThreadLocal原理,Thread内部默认存在一个ThreadLocalMap,线程唯一。set处,通过将ThreadLocal对象作为key设置进Thread#threadLocalMap,下次get时从threadLocalMap将ThreadLocal对象作为key传入,便能获取到set的值。

我们继续分析Looper构造方法,

很简单,创建了一个消息队列,因此MessageQueue也是线程唯一。参数quitAllowed为false,主线程不允许退出。接下来的核心是loop方法,我们跟进。

此处存在无限循环,当loopOnce返回false时,才退出此循环。后面读者会知道,通过主动调用quite方法,此处将返回false。

2,消息的处理

MessageQueue#next是一个阻塞方法,当mQueue返回null时退出,否则会调用到如下逻辑

target是handler,跟进

msg.callback是通过handler.post方法设置的,因此handleCallback简单run,如果设置了mCallback,显然mCallback优先级高于handleMessage方法。

3,消息的到来

回到前述过程,MessageQueue#next方法,这非常重要,我们看下实现。

记住nextPollTimeoutMillis参数,这个是在下文计算nextPollTimeoutMillis值(队头的when字段与当前时间now作差值)。其实整个Looper的底层阻塞实现类似object.wait或condition.await方法,是通过epoll的epoll#await方法实现,epoll#await接收一个参数,当为0时无限等待,否则是一个超时阻塞方法,直到存在事件会唤醒,感兴趣的读者可以去主动了解下linux下的epoll多路复用机制。不过此处,读者简单理解为Object.wait/notify即可。

如果已经唤醒,检查到mMessage(消息头)存在target==null的情况,这就遇到了消息屏障,接下来的逻辑是往后遍历,直到发现一个异步消息,优先处理异步消息。而消息屏障的插入方法在MessageQueue#postSyncBarrier,通常是系统调用,如VIewRootImpl#performTrasfer方法。

笔者假设MessageQueue插入了一个延迟消息,这时MessageQueue内部调用nativeWake方法,nativePollOnce返回,但由于消息延迟,因此计算出nextPollTimeoutMillis重新进入超时阻塞,标记mBlocked为true。否则,返回此消息,标记mBlocked为false,因此此时MessageQueue已经退出阻塞状态,

因此完成了一轮消息处理,直到下次再调用到nativcePollOnce方法进入阻塞。

4,quit相关

通过设置mQuittig为true,然后调用nativeWake将阻塞状态的Queue唤醒,

返回null,进而让Looper#loopOnce返回false,进而退出looper,笔者在这里解释下safe参数。

当safe为true时,只移除msg.when>SystemClock.updateMillis(now)的消息,即当前的消息在执行完毕后才退出,否则移除全部消息,直接退出。

三,相关热门问题的回答

1,主线程Looper.loop无限阻塞不会产生ANR吗?

不会,anr的本质是处理消息超时,此处的阻塞还没有新消息,怎么可能ANR。那消息是怎么到来的呢?一般是用户操控了手机,引发传感器逻辑,system_service进行处理,将要执行的事务通过Binder通知给对应App进程,如ActivityThread#H这个handler,通过Looper发送一个消息,而引发了消息处理的过程。

2,quit和quitSafey区别

是否执行当前when字段满足条件的消息,safe为true时执行,否则不执行。

3,消息屏障是什么?

target为null的消息,优先让异步消息执行。

4,Looper线程唯一吗?

唯一,通过ThreadLocal实现。

5,MessageQueue内部的队列是什么形式?

单链表的优先级队列,Message#when字段作为权重。

如下,从队头开始向后遍历,找到第一个大于when字段的消息A,插入到A的前面。

相关文章:

Android Handler完全解读

一,概述 Handler在Android中比较基础,本文笔者将对此机制做一个完全解读。读者可简单参考上述类图与时序图,便于后续理解。 二,源码解读 1,主线程伊始 众所周知,通过Zygote的fork方式,新创建…...

群晖NAS搭建WebDav结合内网穿透实现公网访问本地影视资源

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默&…...

vmstat 监控虚拟内存,进程,CPU

文章目录 1. 命令格式:2. 命令功能:3. 命令参数:4. 使用实例:实例1:显示虚拟内存使用情况实例2:显示活跃和非活跃内存实例3:查看系统已经fork了多少次实例4:查看内存使用的详细信息实…...

C++: 内联函数

目录 概念: 与宏的对比: 函数膨胀: 内联函数的特性: 概念: 以inline修饰的函数叫做内联函数,编译时C编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数…...

ctfshow web72

下载源码: 开启环境: 本题设置了 open_basedir(),将php所能打开的文件限制在指定的目录树中,包括文件本身。 因为 ini_set() 也被限制了,所以 open_basedir() 不能用 ini_set() 重新设置绕过。 使用 php 伪协议 glob:…...

你想要一个什么样的gpt?高准确度和可靠性 问题解答 自主完成任务(智能体) 解决贫困 战争 难题 公平的价值体系

人们对GPT(为特定用途定制的ChatGPT版本)的期望因用途和需求而异。不过,普遍期望的特征可能包括: 高准确度和可靠性:提供准确、可靠的信息和回答是最基本的要求。用户友好的交互体验:易于使用,…...

VUE中一些概念的理解

Vue 中 computed、mounted 和 methods 的基本理解。 computed 计算属性 (computed):主要用于根据现有的响应式数据(即 data 中的数据或其他 computed 属性)进行计算并返回一个新的值。计算属性是基于它们的响应式依赖进行缓存的。只有当依赖…...

【ArcGIS遇上Python】python实现批量XY坐标生成shp点数据文件

单个手动生成:【ArcGIS风暴】ArcGIS 10.2导入Excel数据X、Y坐标(经纬度、平面坐标),生成Shapefile点数据图层 文章目录 一、问题分析二、解决办法三、注意事项一、问题分析 现有多个excel、txt或者csv格式的坐标数据,需要根据其坐标批量一键生成shp点数据,如下X为经度,…...

【C语言】(7)输入输出

输出 printf printf 是 C 语言中最常用的输出函数。它可以将格式化的字符串输出到控制台。 基本语法: int printf(const char *format, ...);format 是格式化字符串,用于指定输出的格式。... 表示可变数量的参数,根据格式化字符串输出相应…...

数据结构——链式二叉树

目录 🍁一、二叉树的遍历 🌕(一)、前序遍历(Preorder Traversal 亦称先序遍历) 🌕(二)、中序遍历(Inorder Traversal) 🌕(三)、后序遍历(Postorder Traver…...

SpringSecurity笔记

SpringSecurity 本笔记来自三更草堂:https://www.bilibili.com/video/BV1mm4y1X7Hc/?spm_id_from333.337.search-card.all.click,仅供个人学习使用 简介 Spring Security是Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro,…...

常见递归算法题目整理

常见递归算法题目整理 一、单路递归1、阶乘计算2、翻转字符串3、二分查找 二、多路递归1、斐波那契1)基础版2)缓存版 2、汉诺塔3、杨辉三角1)基础版2)缓存版3)优化缓存版 ) 一、单路递归 1、阶乘计算 public class …...

安全小记-Ngnix负载均衡

配置Ngnix环境 1.安装 创建Nginx的目录: mkdir /soft && mkdir /soft/nginx/ cd /home/centos/nginx下载Nginx安装包通过wget命令在线获取安装包: wget https://nginx.org/download/nginx-1.21.6.tar.gz解压Nginx压缩包: tar -x…...

CI/CD

介绍一下CI/CD CI/CD的出现改变了开发人员和测试人员发布软件的方式,从最初的瀑布模型,到最后的敏捷开发(Agile Development),再到今天的DevOps,这是现代开发人员构建出色产品的技术路线 随着DevOps的兴起,出现了持续集成,持续交付和持续部署的新方法,传统的软件开发和交付方…...

window下如何安装ffmpeg(跨平台多媒体处理工具)

ffmpeg是什么? FFmpeg是一个开源的跨平台多媒体处理工具,可以用于录制、转换和流媒体处理音视频。它包含了几个核心库和工具,可以在命令行下执行各种音视频处理操作,如剪辑、分割、合并、媒体格式转换、编解码、流媒体传输等。FFmpeg支持多…...

MySQL必看表设计经验汇总-上(精华版)

目录 1.命名要规范 2选择合适的字段类型 3.主键设计要合理 4.选择合适的字段长度 5.优先考虑逻辑删除,而不是物理删除 6.每个表都需要添加通用字段 7.一张表的字段不宜过多 前言 在数据库设计中,命名规范、合适的字段类型、主键设计、字段长度、…...

扫雷游戏(C语言)

目录 一、前言: 二、游戏规则: 三、游戏前准备 四、游戏实现 1、打印菜单 2、初始化棋盘 3、打印棋盘 4、布置雷 5、排雷 五、完整代码 一、前言: 用C语言完成扫雷游戏对于初学者来说,难度并不是很大,而且通…...

五、MySQL的备份及恢复

5.1 MySQL日志管理 在数据库保存数据时,有时候不可避免会出现数据丢失或者被破坏,这样情况下,我们必须保证数据的安全性和完整性,就需要使用日志来查看或者恢复数据了 数据库中数据丢失或被破坏可能原因: 误删除数据…...

使用dockers-compose搭建开源监控和可视化工具

简介 Prometheus 和 Grafana 是两个常用的开源监控和可视化工具。 Prometheus 是一个用于存储和查询时间序列数据的系统。它提供了用于监控和报警的数据收集、存储、查询和图形化展示能力。Prometheus 使用拉模型(pull model),通过 HTTP 协议…...

浏览器——HTTP缓存机制与webpack打包优化

文章目录 概要强缓存定义开启 关闭强缓存协商缓存工作机制通过Last-Modified If-Modified-Since通过ETag If-None-Match 不使用缓存前端利用缓存机制,修改打包方案webpack 打包webpack 打包名称优化webpack 默认的hash 值webapck其他hash 类型配置webpack打包 web…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...