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

Android IdleHandler源码分析

文章目录

  • Android IdleHandler源码分析
    • 概述
    • 前提
    • 基本用法
    • 源码分析
      • 添加和删除任务
      • 执行任务
    • 应用场景

Android IdleHandler源码分析

概述

IdleHandler是一个接口,它定义在MessageQueue类中,用于在主线程的消息队列空闲时执行一些轻量级的任务。IdleHandler接口有一个方法queueIdle(),其返回值决定了IdleHandler的后续行为。

前提

  • ThreadLocal:线程内的局部变量,存储Looper对象。
  • Looper:处理消息,存储MessageQueue对象。
  • MessageQueue:消息队列,内部维护 Message mMessages ArrayList<IdleHandler> mIdleHandlers
    • mMessages:通过 Handler 发送的消息。
    • mIdleHandlers:列表,存储 IdleHandler 任务。

基本用法

MessageQueue.IdleHandler mIdleHandler = new MessageQueue.IdleHandler() {@Overridepublic boolean queueIdle() {// TODOreturn false;}
};

返回值:

  • false:只执行一次。
  • true:主线程空闲时会继续执行。

源码分析

添加和删除任务

// MessageQueue类
public void addIdleHandler(@NonNull IdleHandler handler) {if (handler == null) {throw new NullPointerException("Can't add a null IdleHandler");}synchronized (this) {mIdleHandlers.add(handler);}
}public void removeIdleHandler(@NonNull IdleHandler handler) {synchronized (this) {mIdleHandlers.remove(handler);}
}

执行任务

最终会调用 MessageQueue#next() 方法。

Message next() { int pendingIdleHandlerCount = -1;// nextPoll超时时间// 如果为-1,表示阻塞等待唤醒// 如果为0,则表示不阻塞// 如果为>0,则表示超时唤醒int nextPollTimeoutMillis = 0;for (;;) {if (nextPollTimeoutMillis != 0) {Binder.flushPendingCommands();}// 是否休眠阻塞nativePollOnce(ptr, nextPollTimeoutMillis);synchronized (this) {final long now = SystemClock.uptimeMillis();Message prevMsg = null;Message msg = mMessages;if (msg != null && msg.target == null) {do {prevMsg = msg;msg = msg.next;} while (msg != null && !msg.isAsynchronous());}if (msg != null) {// 表示MessageQueue有消息if (now < msg.when) {// 就算休眠时间nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);} else {// Got a message.mBlocked = false;if (prevMsg != null) {prevMsg.next = msg.next;} else {mMessages = msg.next;}msg.next = null;if (DEBUG) Log.v(TAG, "Returning message: " + msg);msg.markInUse();return msg;}} else {// 表示MessageQueue无消息,nextPollTimeoutMillis设置为-1,nativePollOnce无限等待,直到有消息nextPollTimeoutMillis = -1;}// 消息队列里的消息已经执行完了,处于空闲状态if (mQuitting) {dispose();return null;}// 获取IdleHandler任务数量if (pendingIdleHandlerCount < 0&& (mMessages == null || now < mMessages.when)) {pendingIdleHandlerCount = mIdleHandlers.size();}// 如果为空,则不执行进入下一个循环if (pendingIdleHandlerCount <= 0) {mBlocked = true;continue;}// 拷贝操作if (mPendingIdleHandlers == null) {mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];}mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);}// 遍历IdleHandler数组for (int i = 0; i < pendingIdleHandlerCount; i++) {final IdleHandler idler = mPendingIdleHandlers[i];mPendingIdleHandlers[i] = null; // 置空boolean keep = false;try {// 执行IdleHanlder任务,调用queueIdle()方法,并获取返回值keep = idler.queueIdle();} catch (Throwable t) {Log.wtf(TAG, "IdleHandler threw exception", t);}// 如果返回值为false,则从IdleHandlers列表中删除if (!keep) {synchronized (this) {mIdleHandlers.remove(idler);}}}// 置空pendingIdleHandlerCount = 0;// 设置为0nextPollTimeoutMillis = 0;}
}

流程说明:

  • 如果本次循环获取的 Message 为空或是一个延迟消息,则表明当前队列为空闲状态。
  • 遍历mIdleHandlers列表,调用queueIdle()方法。
  • queueIdle()的返回值为false,表示从mIdleHandlers列表中删除;返回值为true,表示下次队列空闲时继续调用。

应用场景

  • 启动优化:非必要的代码可以放在 IdleHandler 中处理。
  • 加载优化:通过 IdleHandler 进行预加载。
  • 第三方框架:LeacCanary、Glide。
  • Android系统:GcIdler 空闲时进行GC操作。

相关文章:

Android IdleHandler源码分析

文章目录 Android IdleHandler源码分析概述前提基本用法源码分析添加和删除任务执行任务 应用场景 Android IdleHandler源码分析 概述 IdleHandler是一个接口&#xff0c;它定义在MessageQueue类中&#xff0c;用于在主线程的消息队列空闲时执行一些轻量级的任务。IdleHandle…...

Mac安装stable diffusion 工具

文章目录 1.安装 Homebrew2.安装 stable diffusion webui 的依赖3.下载 stable diffusion webui 代码4.启动 stable diffusion webui 本体5.下载模型6.这里可能会遇到一个clip-vit-large-patch14报错 参考&#xff1a;https://brew.idayer.com/install/stable-diffusion-webui/…...

CVE-2024-6387Open SSH漏洞彻底解决举措(含踩坑内容)

一、漏洞名称 OpenSSH 远程代码执行漏洞(CVE-2024-6387) 二、漏洞概述 Open SSH是基于SSH协议的安全网络通信工具&#xff0c;广泛应用于远程服务器管理、加密文件传输、端口转发、远程控制等多个领域。近日被爆出存在一个远程代码执行漏洞&#xff0c;由于Open SSH服务器端…...

python的简单爬取

需要的第三方模块 requests winr打开命令行输入cmd 简单爬取的基本格式&#xff08;爬取百度logo为例&#xff09; import requests url"http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" resprequests.get(url)#回应 #保存到本地 with open(&…...

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第60集-agent训练资讯APP重点推荐AI资讯内容(含视频)

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第60集-agent训练资讯APP重点推荐AI资讯内容&#xff08;含视频&#xff09; 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。d…...

【学术会议征稿】第三届智能电网与能源系统国际学术会议

第三届智能电网与能源系统国际学术会议 2024 3rd International Conference on Smart Grid and Energy Systems 第三届智能电网与能源系统国际学术会议&#xff08;SGES 2024&#xff09;将于2024年10月25日-27日在郑州召开。 智能电网可以优化能源布局&#xff0c;让现有能源…...

01. 课程简介

1. 课程简介 本课程的核心内容可以分为三个部分&#xff0c;分别是需要理解记忆的计算机底层基础&#xff0c;后端通用组件以及需要不断编码练习的数据结构和算法。 计算机底层基础可以包含计算机网络、操作系统、编译原理、计算机组成原理&#xff0c;后两者在面试中出现的频…...

iOS热门面试题(三)

面试题1&#xff1a;在iOS开发中&#xff0c;什么是MVC设计模式&#xff1f;请详细解释其各个组成部分&#xff0c;并给出一个实际应用场景&#xff0c;包括具体的代码实现。 答案&#xff1a; MVC设计模式是一种在软件开发中广泛使用的架构模式&#xff0c;特别是在iOS开发中…...

ECS中postTransform.Value = float4x4.Scale(1, math.sin(elapsedTime), 1)

在Unity的ECS&#xff08;Entity Component System&#xff09;架构中&#xff0c;postTransform.Value float4x4.Scale(1, math.sin(elapsedTime), 1); 用于设置一个变换矩阵的缩放部分。下面是对这行代码的详细解释&#xff1a; postTransform: 这是一个表示变换的组件或结构…...

VLM技术介绍

1、背景 视觉语言模型&#xff08;Visual Language Models&#xff09;是可以同时从图像和文本中学习以处理许多任务的模型&#xff0c;从视觉问答到图像字幕。 视觉识别&#xff08;如图像分类、物体保护和语义分割&#xff09;是计算机视觉研究中一个长期存在的难题&#xff…...

x264 编码器 AArch64 汇编函数模块关系分析

x264 编码器 AArch64 汇编介绍 x264 是一个流行的开源视频编码器,它实现了 H.264/MPEG-4 AVC 标准。x264 项目致力于提供一个高性能、高质量的编码器,支持多种平台和架构。对于 AArch64(即 64 位 ARM 架构),x264 编码器利用该架构的特性来优化编码过程。在 x264 编码器中,…...

windows10开启防火墙,增加入站规则后不生效,还是不能访问后端程序

一、背景&#xff1a; 公司护网要求开启防火墙&#xff0c;开启防火墙后&#xff0c;前后端分离的项目调试受影响&#xff0c;于是增加入站规则开放固定的后台服务端口&#xff0c;增加的mysql端口3306和redis端口6379&#xff0c;别人都可以访问&#xff0c;但是程序的端口808…...

academic-homepage:快速搭建个人学术主页,页面内容包括个人简介、教育经历、发布过的学术列表等,同时页面布局兼容移动端。

今天给大家分享GitHub 上一个开源的 GitHub Pages 模板 academic-homepage。 可帮助你快速搭建个人学术主页&#xff0c;页面内容包括个人简介、教育经历、发布过的学术列表等最基本内容&#xff0c;同时页面布局兼容移动端。 相关链接 github.com/luost26/academic-homepage …...

.env.development、.env.production、.env.staging

环境变量文件&#xff08;如 .env.development、.env.production、.env.staging&#xff09;用于根据不同的环境&#xff08;开发、生产、测试等&#xff09;配置应用程序的行为。 作用 .env.development&#xff1a;用于开发环境的配置。开发人员在本地开发时会使用这个文件…...

国密证书(gmssl)在Kylin Server V10下安装

1.查看操作系统信息 [root@localhost ~]# cat /etc/.kyinfo [dist] name=Kylin milestone=Server-V10-GFB-Release-ZF9_01-2204-Build03 arch=arm64 beta=False time=2023-01-09 11:04:36 dist_id=Kylin-Server-V10-GFB-Release-ZF9_01-2204-Build03-arm64-2023-01-09 11:04:…...

【数据服务篇】法律快车问答数据:为法律智能化铺就道路

数据来源 法律快车汇集了广泛的法律问题和专业律师的回答&#xff0c;这些来自用户和律师的数据构成了丰富的问答资源。用户通过平台提交各类法律疑问&#xff0c;得到资深律师的详尽解答&#xff0c;形成了一系列真实、多样化的法律案例和讨论。 数据获取见文末。 数据内容…...

各向异性含水层中地下水三维流基本微分方程的推导(二)

各向异性含水层中地下水三维流基本微分方程的推导 参考文献&#xff1a; [1] 刘欣怡,付小莉.论连续性方程的推导及几种形式转换的方法[J].力学与实践,2023,45(02):469-474. 书接上回&#xff1a; 我们能得到三个方向的流入流出平衡方程&#xff1a; ∂ ρ u x ∂ x d x d y d…...

2024 微信小程序 学习笔记 第一天

微信公众平台 (qq.com) 小程序代码的构成 项目结构 JSON 配置文件 WXML 模板 WXSS 样式 JS 逻辑交互 小程序的宿主环境 宿主 通信模型 运行机制 组件 视图组件 view scrioll-view swiper swiper-item swiper属性 text button image image mode属性 小程序API 协…...

PCIe驱动开发(3)— 驱动设备文件的创建与操作

PCIe驱动开发&#xff08;3&#xff09;— 驱动设备文件的创建与操作 一、前言 在 Linux 中一切皆为文件&#xff0c;驱动加载成功以后会在“/dev”目录下生成一个相应的文件&#xff0c;应用程序通过对这个名为“/dev/xxx” (xxx 是具体的驱动文件名字)的文件进行相应的操作即…...

【Redis】简单了解Redis中常用的命令与数据结构

希望文章能给到你启发和灵感&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏 支持一下博主吧&#xff5e; 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、Redis的特点和适用场景三、Redis的数据类型和使用3.1字符串&#xff08;String&…...

绿联 安装SeaTable在线协同表格

绿联 安装SeaTable在线协同表格 1、镜像 seatable/seatable-developer:latest 2、安装 2.1、基础设置 重启策略&#xff1a;容器退出时总是重启容器。 2.2、网络 网络选择桥接(bridge)。 2.3、存储空间 装载路径/shared不可变更。 2.4、端口设置 容器端口固定80&#x…...

终极图像纹理合成工具:GIMP Resynthesizer 完整使用指南

终极图像纹理合成工具&#xff1a;GIMP Resynthesizer 完整使用指南 【免费下载链接】resynthesizer Suite of gimp plugins for texture synthesis 项目地址: https://gitcode.com/gh_mirrors/re/resynthesizer GIMP Resynthesizer 是一套功能强大的 GIMP 纹理合成插件…...

Win11 Edge浏览器频繁断网?3分钟搞定IPv6设置(附DNS优化技巧)

Win11 Edge浏览器频繁断网&#xff1f;深度解析IPv6兼容性问题与DNS优化实战 最近不少Win11用户反馈Edge浏览器频繁断网&#xff0c;而其他应用却正常运作。这种看似诡异的网络问题&#xff0c;往往源于IPv6协议栈的兼容性故障。作为微软新一代操作系统与浏览器的组合&#xff…...

C++的std--ranges视图转换

C的std::ranges视图转换&#xff1a;现代序列处理的利器 在C20中&#xff0c;std::ranges库的引入彻底改变了序列处理的方式&#xff0c;其中视图转换&#xff08;View Adaptors&#xff09;作为核心功能之一&#xff0c;为开发者提供了高效、声明式的数据操作工具。通过视图转…...

JetBrains IDE试用期重置终极指南:3种简单方法快速延长30天免费使用

JetBrains IDE试用期重置终极指南&#xff1a;3种简单方法快速延长30天免费使用 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter JetBrains IDE试用期重置工具&#xff08;ide-eval-resetter&#xff09;是一款专门…...

hadoop+Spark+django基于Spark的影视作品排行榜数据分析和可视化

前言   本研究基于 Spark 框架&#xff0c;构建了一套与可视化系统&#xff0c;旨在为影视行业相关方提供有力支持。研究结合了网络爬虫、Spark 框架、Vue 和 Echarts 等技术&#xff0c;并采用文献研究法展开。 在数据采集阶段&#xff0c;使用 Python 爬虫从多个数据源获取…...

MinerU 2.5-1.2B镜像体验报告:PDF转Markdown,效果远超传统工具

MinerU 2.5-1.2B镜像体验报告&#xff1a;PDF转Markdown&#xff0c;效果远超传统工具 1. 引言&#xff1a;为什么选择MinerU&#xff1f; 1.1 传统工具的局限性 在日常工作中&#xff0c;我们经常需要将PDF文档转换为Markdown格式。传统的工具如PyPDF2、pdfplumber在处理简…...

数字人形象哪里找?lite-avatar形象库150+角色免费使用体验

数字人形象哪里找&#xff1f;lite-avatar形象库150角色免费使用体验 1. 数字人形象获取的痛点与解决方案 在开发数字人应用时&#xff0c;寻找合适的数字人形象往往是第一个拦路虎。传统方式需要自己收集数据、训练模型&#xff0c;这个过程既耗时又耗力&#xff0c;对很多开…...

OpenClaw跨平台同步:Qwen3.5-9B维护多设备代码仓库

OpenClaw跨平台同步&#xff1a;Qwen3.5-9B维护多设备代码仓库 1. 多设备开发的痛点与解决方案 作为一名自由职业开发者&#xff0c;我经常需要在不同设备间切换工作——家里的台式机、咖啡馆的笔记本、客户现场的平板。最让我头疼的是代码版本管理&#xff1a;在A设备修改的…...

STM32duino GNSS库深度解析:Teseo LIV3F驱动与NMEA协议实现

1. 项目概述STM32duino X-NUCLEO-GNSS1A1 是一款面向 STM32 平台的 Arduino 兼容库&#xff0c;专为意法半导体&#xff08;STMicroelectronics&#xff09;推出的 X-NUCLEO-GNSS1A1 GNSS 扩展板设计。该扩展板基于意法半导体自研的 Teseo LIV3F 单芯片 GNSS 接收器&#xff0c…...