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

Android 图形系统之四:Choreographer

Choreographer 是 Android 系统中负责帧同步的核心组件,它协调输入事件、动画和绘制任务,以确保界面以固定频率(通常是每 16ms,一帧)流畅渲染。通过管理 VSYNC 信号和调度任务,Choreographer 是实现流畅 UI 体验和高效资源利用的关键。

在这里插入图片描述
图片参考自UI Performance Rendering

以下是系统性的介绍,结合了作用机制、源码解析,以及典型应用场景。

Choreographer 的作用

  1. 帧同步管理 Choreographer 是 UI 渲染任务的中央调度器,负责以帧为单位同步动画和绘制任务,确保它们在 VSYNC 信号到达时运行。
  2. 协调输入、动画和绘制 它按照固定顺序依次处理输入事件、动画逻辑和界面更新,优化任务间的节奏,防止任务冲突或不必要的渲染。
  3. 减少资源浪费 通过将任务与屏幕刷新(VSYNC)同步,避免了无效的重复绘制,节省了 CPU 和 GPU 的资源。

Choreographer 的工作机制

  1. VSYNC 信号监听 系统底层通过 FrameDisplayEventReceiver 捕获 VSYNC 信号,并通知 Choreographer
  2. 回调机制 提供 postFrameCallback 方法,允许开发者将任务加入帧调度队列,任务会在下一帧按需执行。
  3. 帧的分阶段处理 一帧通常分为以下阶段:
    • Input(输入处理):分发触摸、键盘等输入事件。
    • Animation(动画更新):执行动画计算和逻辑。
    • Traversal(界面遍历):触发视图的测量、布局和绘制。
  4. 线程绑定 每个线程有一个独立的 Choreographer 实例,通常主线程上的 Choreographer 是 UI 渲染的核心。

Choreographer 源码解析

以下是 Choreographer 的核心代码和机制分析。

1. 初始化

Choreographer 的构造方法如下:

private Choreographer(Looper looper, int vsyncSource) {mLooper = looper;mHandler = new FrameHandler(looper);mDisplayEventReceiver = new FrameDisplayEventReceiver(looper, vsyncSource);mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];for (int i = 0; i <= CALLBACK_LAST; i++) {mCallbackQueues[i] = new CallbackQueue();}
}
分析
  • mHandler:基于传入的 Looper 创建,用于任务调度。
  • mDisplayEventReceiver:监听 VSYNC 信号,触发帧更新。
  • mCallbackQueues:维护不同类型的回调队列,如输入、动画和绘制任务。

2. 注册帧回调

开发者可以通过 postFrameCallback 方法注册下一帧需要执行的任务:

public void postFrameCallback(FrameCallback callback) {postFrameCallbackDelayed(callback, 0);
}public void postFrameCallbackDelayed(FrameCallback callback, long delayMillis) {long now = SystemClock.uptimeMillis();long dueTime = now + delayMillis;mCallbackQueues[CALLBACK_ANIMATION].addCallbackLocked(dueTime, callback, null);scheduleFrameLocked(now);
}
分析
  • mCallbackQueues 将任务加入 CALLBACK_ANIMATION 队列。
  • scheduleFrameLocked 检查是否需要安排新的帧。

3. VSYNC 信号处理

VSYNC 信号通过 FrameDisplayEventReceiver 捕获,触发帧调度:

@Override
public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {Message msg = Message.obtain(mHandler, this::doFrame, timestampNanos);msg.setAsynchronous(true);mHandler.sendMessageAtTime(msg, timestampNanos / 1000000);
}
分析
  • onVsync 将信号包装成异步消息,通过 Handler 提交到主线程。
  • 消息最终调用 doFrame,启动任务回调。

4. 帧的处理(doFrame)

doFrame 方法负责执行帧内的所有任务回调:

void doFrame(long frameTimeNanos) {mFrameScheduled = false;doCallbacks(CALLBACK_INPUT, frameTimeNanos);doCallbacks(CALLBACK_ANIMATION, frameTimeNanos);doCallbacks(CALLBACK_TRAVERSAL, frameTimeNanos);
}
分析
  • doCallbacks 按顺序执行输入、动画、布局绘制任务。
  • 每帧回调在帧时间戳(frameTimeNanos)下运行,确保与屏幕刷新同步。

Choreographer 与其他组件的协作

  1. InputEventReceiver 负责捕获触摸和键盘事件,将输入事件调度到 ChoreographerCALLBACK_INPUT
  2. ViewRootImpl 核心视图管理类,依赖 Choreographer 触发测量、布局和绘制阶段。
  3. 动画系统(ValueAnimator/动画框架) 动画更新依赖 CALLBACK_ANIMATION,确保在 VSYNC 同步时平滑执行。

Choreographer 的应用场景

  1. 实现自定义动画 开发者可以通过 postFrameCallback 在下一帧执行自定义动画逻辑,保持与系统的渲染节奏一致。
choreographer.postFrameCallback(frameTimeNanos -> {// 自定义动画逻辑choreographer.postFrameCallback(this);
});
  1. 性能优化
  • 使用工具(如 Perfetto)分析帧间隔,定位卡顿原因。
  • 避免阻塞 CALLBACK_TRAVERSAL 队列,提高帧渲染效率。
  1. 任务分阶段调度 在不同阶段安排任务,确保关键操作在合适的时机执行。

总结

Choreographer 是 Android UI 渲染的核心,通过监听 VSYNC 信号和分阶段调度任务,它能够高效管理输入事件、动画和绘制任务,保证帧同步和流畅的用户体验。深入理解其原理和实现,可以帮助开发者优化 UI 性能,设计更高效、更流畅的应用。

相关文章:

Android 图形系统之四:Choreographer

Choreographer 是 Android 系统中负责帧同步的核心组件&#xff0c;它协调输入事件、动画和绘制任务&#xff0c;以确保界面以固定频率&#xff08;通常是每 16ms&#xff0c;一帧&#xff09;流畅渲染。通过管理 VSYNC 信号和调度任务&#xff0c;Choreographer 是实现流畅 UI…...

CAP定理和BASE理论

CAP定理 CAP定理&#xff0c;也称为布鲁尔定理&#xff08;Brewer’s Theorem&#xff09;&#xff0c;是分布式系统设计中的一个基本原理。它指出在分布式系统中&#xff0c;一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和分区容…...

笔记软件:我来、思源笔记、Obsidian、OneNote

最近wolai的会员到期了&#xff0c;促使我更新了一下笔记软件。 首先&#xff0c;wolai作为一个笔记软件&#xff0c;我觉得有很多做得不错的方面&#xff08;否则我也不会为它付费2年了&#xff09;&#xff0c;各种功能集成得很全&#xff08;公式识别这个功能我写论文的时候…...

试探互联网如何工作?

Reading&#xff1a; How_does_the_Internet_workhow-does-internet-work Watching&#xff1a;How the Internet Works in 5 Minutes Outline: 互联网通过全球互联的计算机和服务器网络工作&#xff0c;通过标准化协议进行通信。数据被分解成数据包&#xff0c;并使用互联…...

【c++笔试强训】(第三十篇)

目录 爱丽丝的⼈偶&#xff08;贪⼼构造&#xff09; 题目解析 讲解算法原理 编写代码 集合&#xff08;排序&#xff09; 题目解析 讲解算法原理 编写代码 爱丽丝的⼈偶&#xff08;贪⼼构造&#xff09; 题目解析 1.题目链接&#xff1a;登录—专业IT笔试面试备考平…...

微信小程序购物车全选反选功能以及合计

微信小程序基于Vant Weapp的购物车功能实现 1、单选 使用微信小程序原生表单组件checkbox和checkbox-group 注意&#xff1a;checkbox原生不支持bind:change事件&#xff0c;checkbox-group支持 <checkbox-group bindchange"handleCheck"><checkbox val…...

vue-qr在线生成二维码组件(vue2版本)

在对于二维码生成中有许多组件&#xff0c;下面介绍关于自定义比较高的vue-qr组件&#xff0c;能自定义设置背景颜色、背景图片、背景Gif图、实点和空白区的颜色、中心Logo的图片和边距。 依赖下载 注意&#xff1a; 直接npm下载最新版 有些项目可能运行会抱错 这时候你可以降…...

大语言模型技术相关知识-笔记整理

系列文章目录 这个系列攒了很久。主要是前段之间面试大语言模型方面的实习&#xff08;被拷打太多次了&#xff09;&#xff0c;然后每天根据面试官的问题进行扩展和补充的这个笔记。内容来源主要来自视频、个人理解以及官方文档中的记录。方便后面的回顾。 文章目录 系列文章…...

SCP命令实现Linux中的文件传输

CP命令的主要作用是实现Linux与Linux系统之间的文件传输。 SCP命令时基于SSH协议,所以两台服务器的sshd服务必须处于开启状态,否则无法完成上传与下载操作。 #1.上传文件 scp linux本地文件路径 远程用户名@linux主机地址:远程路径 #2.下载文件 scp 远程用户名@linux主机地址…...

linux环境中后台运行java程序

在生产环境&#xff0c;我们通常需要让java进程后台运行&#xff0c;并且即使会话关闭&#xff0c;进程也依然存在。 使用的命令&#xff1a; nohup java -jar xxx.jar -> aaa.log 2>&1 & 详细介绍下上面这条命令 &#xff08;1&#xff09;nohup&#xff1a;…...

Go学习:变量

目录 1. 变量的命名 2. 变量的声明 3. 变量声明时注意事项 4. 变量的初始化 5. 简单例子 变量主要用来存储数据信息&#xff0c;变量的值可以通过变量名进行访问。 1. 变量的命名 在Go语言中&#xff0c;变量名的命名规则 与其他编程语言一样&#xff0c;都是由字母、数…...

在Unity编辑模式下运行Mono中的方法

[ExecuteAlways] 最简单的方法当然是直接给Mono加上[ExecuteAlways]修饰&#xff0c;这样Mono中的Awake&#xff0c;Update等等都可以在编辑模式下按照原本的时机运行。 [ExecuteAlways] public class TestScript : MonoBehaviour {void TestMethod(){Debug.Log("TestMe…...

Y20030028 JAVA+SSM+MYSQL+LW+基于JAVA的考研监督互助系统的设计与实现 源代码 配置 文档

基于JAVA的考研监督互助系统 1.项目描述2. 课题开发背景及意义3.项目功能4.界面展示5.源码获取 1.项目描述 随着高等教育的普及和就业竞争的加剧&#xff0c;越来越多的学生选择继续深造&#xff0c;参加研究生入学考试。考研人数的不断增加&#xff0c;使得考研过程中的学习监…...

MATLAB期末复习笔记(下)

目录 五、数据和函数的可视化 1.MATLAB的可视化对象 2.二维图形的绘制 3.图形标识 4.多子图绘图 5.直方图的绘制 &#xff08;1&#xff09;分类 &#xff08;2&#xff09;垂直累计式 &#xff08;3&#xff09;垂直分组式 &#xff08;4&#xff09;水平分组式 &…...

「Mac畅玩鸿蒙与硬件37」UI互动应用篇14 - 随机颜色变化器

本篇将带你实现一个随机颜色变化器应用。用户点击“随机颜色”按钮后&#xff0c;界面背景会随机变化为淡色系颜色&#xff0c;同时显示当前的颜色代码&#xff0c;页面还会展示一只猫咪图片作为装饰&#xff0c;提升趣味性。 关键词 UI互动应用随机颜色生成状态管理用户交互…...

MySql:理解数据库

目录 一、什么是数据库 第一层理解 第二层理解 第三层理解 二、Linux下的数据库 三、基本认识 登录数据库时&#xff0c; mysql -u root -h 127.0.0.1 -P 3306 -p -h指定MySql服务器所在主机&#xff0c;若在本地则为回环地址。-P表示目标主机上MySql服务端口号 一般简单…...

学习笔记051——SpringBoot学习2

文章目录 Spring Boot 原理1、SpringBootConfiguration2、ConfigurationProperties3、ComponentScan4、EnableAutoConfiguration Spring Boot 原理 Spring Boot 可以自动读取配置文件&#xff0c;将项目所需要的组件全部自动加载到 IoC 容器中&#xff0c;包括两部分 开发者自…...

crush rule 20 type does not match pool

问题 kubectl describe CephObjectStore ceph-objectstoreEvents:Type Reason Age From Message---- ------ ---- ---- -------Warning ReconcileFailed 14m …...

BA是什么?

目录 1.EKF的步骤 一、问题定义与模型建立 二、线性化处理 三、应用卡尔曼滤波 四、迭代与收敛 五、结果评估与优化 注意事项 2.BA问题的步骤 一、问题定义与数据准备 二、构建优化模型 三、选择优化算法 四、执行优化过程 五、结果评估与优化 六、应用与验证 1.…...

通过docker 搭建jenkins环境;

一、官网简介使用安装说明: How to use this image docker run -p 8080:8080 -p 50000:50000 jenkins This will store the workspace in /var/jenkins_home. All Jenkins data lives in there - including plugins and configuration. You will probably want to make that …...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...