当前位置: 首页 > 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&…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...