卡顿检测与 Choreographer 原理
一、卡顿检测的原理
卡顿的本质是主线程(UI 线程)未能及时完成某帧的渲染任务(超过 16.6ms,以 60Hz 屏幕为例),导致丢帧(Frame Drop)。检测卡顿的核心思路是监控主线程任务的执行时间。
常见检测方法:
-
主线程监控(Looper Printer)
- 原理:利用
Looper
的Printer
机制,在每条消息处理前后打印日志,统计消息执行时间。 - 代码示例:
Looper.getMainLooper().setMessageLogging(printer -> {if (printer.startsWith(">>>>> Dispatching")) {startTime = System.currentTimeMillis();} else if (printer.startsWith("<<<<< Finished")) {long cost = System.currentTimeMillis() - startTime;if (cost > 16) reportBlock(cost);} });
- 原理:利用
-
Choreographer FrameCallback
- 原理:通过向
Choreographer
注册FrameCallback
,在每一帧开始绘制时触发回调,计算帧耗时。 - 代码示例:
Choreographer.getInstance().postFrameCallback(new FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {long current = System.currentTimeMillis();if (lastFrameTime > 0) {long cost = current - lastFrameTime;if (cost > 16) reportJank(cost);}lastFrameTime = current;Choreographer.getInstance().postFrameCallback(this); // 持续监控} });
- 原理:通过向
-
Systrace/Perfetto
- 原理:系统级工具,通过插桩代码和内核事件,分析每一帧的耗时及卡顿原因。
-
BlockCanary 等开源库
- 原理:基于主线程监控,结合堆栈采样,定位耗时方法。
二、Choreographer 的工作原理
Choreographer
是 Android 渲染系统的核心协调者,负责接收 VSync 信号并调度 UI 渲染流程。
1. 核心职责
- 接收来自 SurfaceFlinger 的 VSync 信号(垂直同步信号,通常 60Hz)。
- 按优先级调度以下任务:
- INPUT(输入事件)
- ANIMATION(属性动画)
- TRAVERSAL(View 的 measure/layout/draw)
- COMMIT(提交渲染结果)
2. 关键流程
-
VSync 信号到达
- 由硬件或软件模拟生成,通知应用开始新一帧的渲染。
-
任务调度(Choreographer)
Choreographer
根据 VSync 信号,依次触发注册的FrameCallback
。- 调用
doFrame()
方法,依次处理输入、动画、视图遍历等任务。
-
UI 渲染阶段
- Measure/Layout/Draw:View 系统遍历视图树,生成绘制命令。
- Sync & Upload:将 UI 数据同步到 RenderThread。
- Draw:RenderThread 通过 OpenGL/Vulkan 将数据提交给 GPU。
-
提交到 SurfaceFlinger
- 最终由 SurfaceFlinger 合成所有 Layer,输出到屏幕。
3. 代码流程
// Choreographer 核心逻辑
void doFrame(long frameTimeNanos, int frame) {// 1. 计算掉帧情况if (jitterNanos >= mFrameIntervalNanos) {Log.w(TAG, "Frame time jitter: " + jitterNanos);}// 2. 按顺序处理任务mFrameInfo.markInputHandlingStart();doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);mFrameInfo.markAnimationsStart();doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);mFrameInfo.markPerformTraversalsStart();doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
}
三、卡顿与 Choreographer 的关系
-
卡顿的根本原因
- 主线程在
doFrame()
中执行的任务(如 View 绘制、动画计算)耗时过长,导致未能在下一个 VSync 信号到来前完成渲染。
- 主线程在
-
Choreographer 的监控能力
- 通过
postFrameCallback
可以精确测量两帧之间的时间差,判断是否发生丢帧。 - 系统内部会统计
jankyFrames
(掉帧数),并通过onJankyFrames
回调通知应用。
- 通过
四、优化卡顿的建议
- 减少主线程任务
- 耗时操作(IO、网络、计算)移至子线程。
- 优化 View 层级
- 避免过度绘制,减少
measure/layout/draw
耗时。
- 避免过度绘制,减少
- 合理使用动画
- 优先使用硬件加速的属性动画(如
ViewPropertyAnimator
)。
- 优先使用硬件加速的属性动画(如
- 监控工具结合
- 使用
Systrace
分析渲染流水线,定位阻塞点。
- 使用
总结
- 卡顿检测依赖对主线程任务耗时的监控,可通过多种工具实现。
- Choreographer 是 Android 渲染系统的中枢,通过 VSync 信号驱动 UI 渲染流程,其调度机制直接影响帧率稳定性。
- 深入理解这两者的原理,是优化应用流畅性的关键基础。
相关文章:
卡顿检测与 Choreographer 原理
一、卡顿检测的原理 卡顿的本质是主线程(UI 线程)未能及时完成某帧的渲染任务(超过 16.6ms,以 60Hz 屏幕为例),导致丢帧(Frame Drop)。检测卡顿的核心思路是监控主线程任务的执行时…...

Baklib加速企业AI数据智理转型
Baklib智理AI数据资产 在AI技术深度渗透业务场景的背景下,Baklib通过构建企业级知识中台架构,重塑了数据资产的治理范式。该平台采用智能分类引擎与语义分析模型,将分散在邮件、文档、数据库中的非结构化数据转化为标准化的知识单元…...

基于协同过滤的文学推荐系统设计【源码+文档+部署】
基于协同过滤的文学推荐系统设计 摘要 随着信息技术的飞速发展和文学阅读需求的日益多样化,构建一个高效、精准的文学推荐系统变得尤为重要。本文采用Spring Boot框架,结合协同过滤算法,设计并实现了一个基于用户借阅行为和社交论坛互动的文学…...
在c/c++中,如何使用链表进行插入、删除和遍历功能。
首先,链表由节点组成,每个节点应该包含数据和指向下一个节点的指针。 结构体可以包含数据域和指针域。 比如,假设链表存储整数,那节点的结构体应该有一个int类型的数据和一个指向同样结构体的指针。结构体定义大概是这样的&…...

数据结构与算法——单链表(续)
单链表(续) 查找在指定位置之前插入结点在指定位置之后插入结点删除pos位置的结点删除pos位置之后的结点销毁 查找 遍历:pcur指向头结点,循环,当pucr不为空进入循环,pucr里面指向的数据为要查找的值的时候…...

全面且深度学习c++类和对象(上)
文章目录 过程和对象类的引入,类的定义类的访问限定符及封装类的访问限定符封装 类的实例化类大小内存对齐规则: this指针this特性 过程和对象 C语言面向过程设计,c面向对象设计, 举例:洗衣服 C语言:放衣服…...

开源情报如何成为信息攻防的关键资源
相比于传统情报,开源情报具有情报数量大、情报质量好、情报成本低、情报可用性强等优势。这是开源情报能够成为信息攻防关键资源的主要原因。 海量信息让开源情报具有更大潜力。一是开源情报体量巨大。信息化时代是信息爆炸的时代,网络上发布的各种信息…...

【风控】用户特征画像体系
一、体系架构概述 1.1 核心价值定位 风控特征画像体系是通过多维度数据融合分析,构建客户风险全景视图的智能化工具。其核心价值体现在: 全周期覆盖:贯穿客户生命周期的营销、贷前、贷中、贷后四大场景立体化刻画:整合基础数据…...
Android开发-文本输入
在Android应用开发中,文本输入是用户与应用交互的最常见方式之一。无论是登录界面、搜索框还是表单填写,都需要处理用户的文本输入。本文将介绍如何在Android应用中实现和管理文本输入,包括基本控件的使用、事件监听、输入验证以及一些高级功…...

Unity:场景管理系统 —— SceneManagement 模块
目录 🎬 什么是 Scene(场景)? Unity 项目中的 Scene 通常负责什么? 🌍 一个 Scene 包含哪些元素? Scene 的切换与管理 📁 如何创建与管理 Scenes? 什么是Scene Man…...
elementUI源码学习
学习笔记。 最近在看element的table表格优化,又去看了一下element源码框架。element 的架构是很优秀,通过大量的脚本实现工程化,让组件库的开发者专注于事情本身,比如新加组件,一键生成组件所有文件,并完成…...

SZU 编译原理
总结自 深圳大学《编译原理》课程所学相关知识。 文章目录 文法语法分析自顶向下的语法分析递归下降分析LL(1) 预测分析法FIRST 集合FOLLOW 集合 文法 乔姆斯基形式语言理论: 表达能力:0型文法 > 1型文法 > 2型文法 > 3型文法。 0 型文法&am…...
实时技术方案对比:SSE vs WebSocket vs Long Polling
早期网站仅展示静态内容,而如今我们更期望:实时更新、即时聊天、通知推送和动态仪表盘。 那么要如何实现实时的用户体验呢?三大经典技术各显神通: SSE(Server-Sent Events):轻量级单向数据流WebSocket:双向全双工通信Long Polling(长轮询):传统过渡方案假设目前有三…...

【程序员AI入门:模型】19.开源模型工程化全攻略:从选型部署到高效集成,LangChain与One-API双剑合璧
一、模型选型与验证:精准匹配业务需求 (一)多维度评估体系 通过量化指标权重实现科学选型,示例代码计算模型综合得分: # 评估指标权重与模型得分 requirements {"accuracy": 0.4, "latency": …...
北斗导航 | 基于深度学习的卫星导航数据训练——检测识别故障卫星
深度学习+故障卫星识别 **1. 数据准备与预处理****2. 模型选择与设计****3. 训练策略****4. 模型优化与验证****5. 实时部署与集成****6. 持续学习与更新****示例模型架构(LSTM + Attention)****挑战与解决方案**🥦🥦🥦🥦🥦🥦🥦🥕🥦🥦🥦🥦🥦🥦�…...

ARM Cortex-M3内核详解
目录 一、ARM Cortex-M3内核基本介绍 (一)基本介绍 (二)主要组成部分 (三)调试系统 二、ARM Cortex-M3内核的内核架构 三、ARM Cortex-M3内核的寄存器 四、ARM Cortex-M3内核的存储结构 五、ARM Co…...
基于Unity的简单2D游戏开发
基于Unity的简单2D游戏开发 摘要 本文围绕基于Unity的简单2D游戏开发进行深入探讨,旨在分析其开发过程中的技术架构与实现策略。通过文献综述与市场分析,研究发现,近年来Unity引擎因其优秀的跨平台特性及可视化编程理念,成为2D游戏开发的主要工具。文章首先梳理了游戏开发的…...
Linux系统编程——exec族函数
我们来完整、系统、通俗地讲解 Linux 系统编程中非常重要的一类函数:exec 族函数(也叫 exec family)。 一、什么是 exec? exec 系列函数的作用是: 用一个新的程序,替换当前进程的内容。 也就是说…...

ThinkStation图形工作站进入BIOS方法
首先视频线需要接在独立显卡上,重新开机,持续按F1,或者显示器出来lenovo的logo的时候按F1,这样就进到bios里了。联*想*坑,戴尔贵。靠。...

go 集成base64Captcha 支持多种验证码
base64Captcha 是一个基于 Go 语言开发的验证码生成库,主要用于在 Web 应用中集成验证码功能,以增强系统的安全性。以下是其主要特点和简介: base64Captcha主要功能 验证码类型丰富:支持生成多种类型的验证码,包括纯…...

【C语言字符函数和字符串函数(一)】--字符分类函数,字符转换函数,strlen,strcpy,strcat函数的使用和模拟实现
目录 一.字符分类函数 1.1--字符分类函数的理解 1.2--字符分类函数的使用 二.字符转换函数 2.1--字符转换函数的理解 2.2--字符转换函数的使用 三.strlen的使用和模拟实现 3.1--strlen的使用演示 3.2--strlen的返回值 3.3--strlen的模拟实现 四.strcpy的使用和模拟实现…...
deepseek问答记录:请讲解一下hugingface transformers中的AutoProcessor
Hugging Face Transformers库中的AutoProcessor是一个用于自动加载与预训练模型配套的处理器的工具类。它简化了预处理流程,特别适用于多模态模型(如同时处理文本、图像、音频的模型)。以下是详细讲解: 1. AutoProcessor的功能 •…...

大模型基础之量化
概述 量化,Quantization,机器学习和深度学习领域是一种用于降低计算复杂度、减少内存占用、加速推理的优化方法。定义:将模型中的数据从高精度表示转换为低精度表示。主要目的是为了减少模型的存储需求和计算复杂度,同时尽量减少…...

游戏引擎学习第286天:开始解耦实体行为
回顾并为今天的内容定下基调 我们目前正在进入实体系统的一个新阶段,之前我们已经让实体的移动系统变得更加灵活,现在我们想把这个思路继续延伸到实体系统的更深层次。今天的重点,是重新审视我们处理实体类型(entity type&#x…...

win10-django项目与mysql的基本增删改查
以下都是在win10系统下,django项目的orm框架对本地mysql的表的操作 models.py----->即表对应的类所在的位置 在表里新增数据 1.引入表对应的在models.py中的类class 2.在views.py中使用函数:类名.objects.create(字段名值,字段名"值"。。。…...
Windows 本地部署MinerU详细教程
📖 项目概述 MinerU是一款由OpenDataLab开发的开源PDF转Markdown工具,可以高质量地提取PDF文档内容,生成结构化的Markdown格式文本。本指南将帮助您在本地部署并使用MinerU。 ⭐ 功能特性 MinerU具有以下核心功能: ✨ 文档处理…...

动态范围调整(SEF算法实现)
一、背景介绍 继续在整理对比度调整相关算法,发现一篇单帧动态范围提升的算法:Simulated Exposure Fusion,论文表现看起来很秀,这里尝试对它进行了下效果复现。 二、实现流程 1、基本原理 整体来说,大致可以分为两步…...

SpringCloud微服务开发与实战
本节内容带你认识什么是微服务的特点,微服务的拆分,会使用Nacos实现服务治理,会使用OpenFeign实现远程调用(通过黑马商城来带你了解实际开发中微服务项目) 前言:从谷歌搜索指数来看,国内从自201…...

WAS和Tomcat的对比
一、WAS和Tomcat的对比 WebSphere Application Server (WAS) 和 Apache Tomcat 是两款常用的 Java 应用服务器,但它们有许多显著的区别。在企业级应用中,它们扮演不同的角色,各自有其特点和适用场景。以下是它们在多个维度上的详细对比&…...
Rust 数据结构:String
Rust 数据结构:String Rust 数据结构:String什么是字符串?创建新字符串更新字符串将 push_str 和 push 附加到 String 对象后使用 运算符和 format! 宏 索引到字符串字符串在内存中的表示字节、标量值和字形簇 分割字符串遍历字符串的方法 R…...