卡顿检测与 Choreographer 原理

一、卡顿检测的原理

卡顿的本质是主线程(UI 线程)未能及时完成某帧的渲染任务(超过 16.6ms,以 60Hz 屏幕为例),导致丢帧(Frame Drop)。检测卡顿的核心思路是监控主线程任务的执行时间

常见检测方法:
  1. 主线程监控(Looper Printer)

    • 原理:利用 LooperPrinter 机制,在每条消息处理前后打印日志,统计消息执行时间。
    • 代码示例:
      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);}
      });
      
  2. 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); // 持续监控}
      });
      
  3. Systrace/Perfetto

    • 原理:系统级工具,通过插桩代码和内核事件,分析每一帧的耗时及卡顿原因。
  4. BlockCanary 等开源库

    • 原理:基于主线程监控,结合堆栈采样,定位耗时方法。

二、Choreographer 的工作原理

Choreographer 是 Android 渲染系统的核心协调者,负责接收 VSync 信号并调度 UI 渲染流程。

1. 核心职责
  • 接收来自 SurfaceFlinger 的 VSync 信号(垂直同步信号,通常 60Hz)。
  • 按优先级调度以下任务:
    • INPUT(输入事件)
    • ANIMATION(属性动画)
    • TRAVERSAL(View 的 measure/layout/draw)
    • COMMIT(提交渲染结果)
2. 关键流程
  1. VSync 信号到达

    • 由硬件或软件模拟生成,通知应用开始新一帧的渲染。
  2. 任务调度(Choreographer)

    • Choreographer 根据 VSync 信号,依次触发注册的 FrameCallback
    • 调用 doFrame() 方法,依次处理输入、动画、视图遍历等任务。
  3. UI 渲染阶段

    • Measure/Layout/Draw:View 系统遍历视图树,生成绘制命令。
    • Sync & Upload:将 UI 数据同步到 RenderThread。
    • Draw:RenderThread 通过 OpenGL/Vulkan 将数据提交给 GPU。
  4. 提交到 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 的关系

  1. 卡顿的根本原因

    • 主线程在 doFrame() 中执行的任务(如 View 绘制、动画计算)耗时过长,导致未能在下一个 VSync 信号到来前完成渲染。
  2. Choreographer 的监控能力

    • 通过 postFrameCallback 可以精确测量两帧之间的时间差,判断是否发生丢帧。
    • 系统内部会统计 jankyFrames(掉帧数),并通过 onJankyFrames 回调通知应用。

四、优化卡顿的建议

  1. 减少主线程任务
    • 耗时操作(IO、网络、计算)移至子线程。
  2. 优化 View 层级
    • 避免过度绘制,减少 measure/layout/draw 耗时。
  3. 合理使用动画
    • 优先使用硬件加速的属性动画(如 ViewPropertyAnimator)。
  4. 监控工具结合
    • 使用 Systrace 分析渲染流水线,定位阻塞点。

总结

  • 卡顿检测依赖对主线程任务耗时的监控,可通过多种工具实现。
  • Choreographer 是 Android 渲染系统的中枢,通过 VSync 信号驱动 UI 渲染流程,其调度机制直接影响帧率稳定性。
  • 深入理解这两者的原理,是优化应用流畅性的关键基础。

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

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

相关文章

物联网僵尸网络防御:从设备认证到流量染色

一、IoT设备的安全困境 典型物联网设备存在硬编码密钥问题&#xff1a; // 固件中的危险代码示例 const char* DEFAULT_KEY "A1B2-C3D4-E5F6"; // 厂商预设密钥 void connect_server() {authenticate(DEFAULT_KEY); // 密钥从未更新 }此类漏洞导致某智能家居平台…

二叉树子树判断:从递归到迭代的全方位解析

一、题目解析 题目描述 给定两棵二叉树root和subRoot&#xff0c;判断root中是否存在一棵子树&#xff0c;其结构和节点值与subRoot完全相同。 示例说明 示例1&#xff1a; root [3,4,5,1,2]&#xff0c;subRoot [4,1,2] 返回true&#xff0c;因为root的左子树与subRoot完…

Springboot 异步场景 使用注解 @Async 及 自定义线程池分模块使用

目录 前言一、Springboot项目如何开启异步&#xff1f;二、存在的问题三、自定义线程池四、自定义线程池使用五、阻塞队列和拒绝策略 前言 当开发中遇到不影响主流程任务时&#xff0c;使用异步去处理。 如有以下场景&#xff1a; 1、业务需要生成一个季度的数据进行员工排名&…

【GNN笔记】Signed Graph Convolutional Network(12)【未完】

视频链接&#xff1a;《图神经网络》 Signed Graph Convolutional Network 之前介绍的GNN模型主要集中在无符号的网络&#xff08;或仅由正链接组成的图&#xff09;上&#xff0c;符号 图带来的挑战&#xff0c;主要集中在于 否定链接&#xff0c;与正链接相比&#xff0c;它不…

米勒电容补偿的理解

米勒电容补偿是使运放放大器稳定的重要手法&#xff0c;可以使两级运放的两个极点分离&#xff0c;从而可以得到更好的相位裕度。 Miller 电容补偿的本质是增加一条通路流电流&#xff0c;流电流才是miller效应的本质。给定一个相同的输入&#xff0c;Miller 电容吃掉的电流比…

CVE-2017-8046 漏洞深度分析

漏洞概述 CVE-2017-8046 是 Spring Data REST 框架中的一个高危远程代码执行漏洞&#xff0c;影响版本包括 Spring Data REST < 2.5.12、2.6.7、3.0 RC3 及关联的 Spring Boot 和 Spring Data 旧版本。攻击者通过构造包含恶意 SpEL&#xff08;Spring Expression Language&…

qt文本边框设置

// 计算文本的大致尺寸 QFontMetrics fm(textEditor->font()); QRect textRect fm.boundingRect(textItem->toPlainText()); // 设置编辑框大小&#xff0c;增加一些边距 const int margin 10; textEditor->setGeometry( center.x() - textRect.width()/2 - margin,…

Java 与 面向对象编程(OOP)

Java 是典型的纯面向对象编程语言&#xff08;Pure Object-Oriented Language&#xff09;&#xff0c;其设计严格遵循面向对象&#xff08;OOP&#xff09;的核心原则。以下是具体分析&#xff1a; 1. Java 的面向对象核心特性 (1) 一切皆对象 Java 中几乎所有的操作都围绕…

导出导入Excel文件(详解-基于EasyExcel)

前言&#xff1a; 近期由于工作的需要&#xff0c;根据需求需要导出导入Excel模板。于是自学了一下下&#xff0c;在此记录并分享&#xff01;&#xff01; EasyExcel&#xff1a; 首先我要在这里非常感谢阿里的大佬们&#xff01;封装这么好用的Excel相关的API&#xff0c;真…

python版本管理工具-pyenv轻松切换多个Python版本

在使用python环境开发时&#xff0c;相信肯定被使用版本所烦恼&#xff0c;在用第三方库时依赖兼容的python版本不一样&#xff0c;有没有一个能同时安装多个python并能自由切换的工具呢&#xff0c;那就是pyenv&#xff0c;让你可以轻松切换多个Python 版本。 pyenv是什么 p…

Elasticsearch 索引副本数

作者&#xff1a;来自 Elastic Kofi Bartlett 解释如何配置 number_of_replicas、它的影响以及最佳实践。 更多阅读&#xff1a;Elasticsearch 中的一些重要概念: cluster, node, index, document, shards 及 replica 想获得 Elastic 认证&#xff1f;查看下一期 Elasticsearc…

AXI4总线协议 ------ AXI_LITE协议

一、AXI 相关知识介绍 https://download.csdn.net/download/mvpkuku/90841873 AXI_LITE 选出部分重点&#xff0c;详细文档见上面链接。 1.AXI4 协议类型 2.握手机制 二、AXI_LITE 协议的实现 1. AXI_LITE 通道及各通道端口功能介绍 2.实现思路及框架 2.1 总体框架 2.2 …

idea运行

各种小kips Linuxidea上传 Linux 部署流程 1、先在idea打好jar包&#xff0c;clean之后install 2、在Linux目录下&#xff0c;找到对应项目目录&#xff0c;把原来的jar包放在bak文件夹里面 3、杀死上一次jar包的pid ps -ef|grep cliaidata.jar kill pid 4、再进行上传新的jar…

FPGA: XILINX Kintex 7系列器件的架构

本文将详细介绍Kintex-7系列FPGA器件的架构。以下内容将涵盖Kintex-7的核心架构特性、主要组成部分以及关键技术&#xff0c;尽量全面且结构化&#xff0c;同时用简洁的语言确保清晰易懂。 Kintex-7系列FPGA架构概述 Kintex-7是Xilinx 7系列FPGA中的中高端产品线&#xff0c;基…

【LLM】大模型落地应用的技术 ——— 推理训练 MOE,AI搜索 RAG,AI Agent MCP

【LLM】大模型落地应用的技术 ——— 推理训练MOE&#xff0c;AI搜索RAG&#xff0c;AI Agent MCP 文章目录 1、推理训练 MOE2、AI搜索 RAG3、AI Agent MCP 1、推理训练 MOE MoE 是模型架构革新&#xff0c;解决了算力瓶颈。原理是多个专家模型联合计算。 推理训练MoE&#xff…

10 web 自动化之 yaml 数据/日志/截图

文章目录 一、yaml 数据获取二、日志获取三、截图 一、yaml 数据获取 需要安装 PyYAML 库 import yaml import os from TestPOM.common import dir_config as Dir import jsonpathclass Data:def __init__(self,keyNone,file_name"test_datas.yaml"):file_path os…

中exec()函数因$imagePath参数导致的命令注入漏洞

exec(zbarimg -q . $imagePath, $barcodeList, $returnVar); 针对PHP中exec()函数因$imagePath参数导致的命令注入漏洞&#xff0c;以下是安全解决方案和最佳实践&#xff1a; 一、漏洞原理分析 直接拼接用户输入$imagePath到系统命令中&#xff0c;攻击者可通过注入特殊字…

this.$set的用法-响应式数据更新

目录 一、核心作用 三、使用场景与示例 1. 给对象添加新属性 四、与 Vue.set 的关系 五、底层原理 六、Vue 3 的替代方案 七、最佳实践 八、常见问题 Q&#xff1a;为什么修改嵌套对象属性不需要 $set&#xff1f; Q&#xff1a;$set 和 $forceUpdate 的区别&#xf…

【生成式AI文本生成实战】DeepSeek系列应用深度解析

目录 &#x1f31f; 前言&#x1f3d7;️ 技术背景与价值&#x1fa79; 当前技术痛点&#x1f6e0;️ 解决方案概述&#x1f465; 目标读者说明 &#x1f9e0; 一、技术原理剖析&#x1f4ca; 核心概念图解&#x1f4a1; 核心作用讲解&#x1f527; 关键技术模块说明⚖️ 技术选…

c/c++的opencv的图像预处理讲解

OpenCV 图像预处理核心技术详解 (C/C) 图像预处理是计算机视觉任务中至关重要的一步。原始图像往往受到噪声、光照不均、尺寸不一等多种因素的影响&#xff0c;直接用于后续分析&#xff08;如特征提取、目标检测、机器学习模型训练等&#xff09;可能会导致性能下降或结果不准…