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

图片参考自UI Performance Rendering
以下是系统性的介绍,结合了作用机制、源码解析,以及典型应用场景。
Choreographer 的作用
- 帧同步管理
Choreographer是 UI 渲染任务的中央调度器,负责以帧为单位同步动画和绘制任务,确保它们在 VSYNC 信号到达时运行。 - 协调输入、动画和绘制 它按照固定顺序依次处理输入事件、动画逻辑和界面更新,优化任务间的节奏,防止任务冲突或不必要的渲染。
- 减少资源浪费 通过将任务与屏幕刷新(VSYNC)同步,避免了无效的重复绘制,节省了 CPU 和 GPU 的资源。
Choreographer 的工作机制
- VSYNC 信号监听 系统底层通过
FrameDisplayEventReceiver捕获 VSYNC 信号,并通知Choreographer。 - 回调机制 提供
postFrameCallback方法,允许开发者将任务加入帧调度队列,任务会在下一帧按需执行。 - 帧的分阶段处理 一帧通常分为以下阶段:
- Input(输入处理):分发触摸、键盘等输入事件。
- Animation(动画更新):执行动画计算和逻辑。
- Traversal(界面遍历):触发视图的测量、布局和绘制。
- 线程绑定 每个线程有一个独立的
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 与其他组件的协作
- InputEventReceiver 负责捕获触摸和键盘事件,将输入事件调度到
Choreographer的CALLBACK_INPUT。 - ViewRootImpl 核心视图管理类,依赖
Choreographer触发测量、布局和绘制阶段。 - 动画系统(ValueAnimator/动画框架) 动画更新依赖
CALLBACK_ANIMATION,确保在 VSYNC 同步时平滑执行。
Choreographer 的应用场景
- 实现自定义动画 开发者可以通过
postFrameCallback在下一帧执行自定义动画逻辑,保持与系统的渲染节奏一致。
choreographer.postFrameCallback(frameTimeNanos -> {// 自定义动画逻辑choreographer.postFrameCallback(this);
});
- 性能优化
- 使用工具(如 Perfetto)分析帧间隔,定位卡顿原因。
- 避免阻塞 CALLBACK_TRAVERSAL 队列,提高帧渲染效率。
- 任务分阶段调度 在不同阶段安排任务,确保关键操作在合适的时机执行。
总结
Choreographer 是 Android UI 渲染的核心,通过监听 VSYNC 信号和分阶段调度任务,它能够高效管理输入事件、动画和绘制任务,保证帧同步和流畅的用户体验。深入理解其原理和实现,可以帮助开发者优化 UI 性能,设计更高效、更流畅的应用。
相关文章:
Android 图形系统之四:Choreographer
Choreographer 是 Android 系统中负责帧同步的核心组件,它协调输入事件、动画和绘制任务,以确保界面以固定频率(通常是每 16ms,一帧)流畅渲染。通过管理 VSYNC 信号和调度任务,Choreographer 是实现流畅 UI…...
CAP定理和BASE理论
CAP定理 CAP定理,也称为布鲁尔定理(Brewer’s Theorem),是分布式系统设计中的一个基本原理。它指出在分布式系统中,一致性(Consistency)、可用性(Availability)和分区容…...
笔记软件:我来、思源笔记、Obsidian、OneNote
最近wolai的会员到期了,促使我更新了一下笔记软件。 首先,wolai作为一个笔记软件,我觉得有很多做得不错的方面(否则我也不会为它付费2年了),各种功能集成得很全(公式识别这个功能我写论文的时候…...
试探互联网如何工作?
Reading: How_does_the_Internet_workhow-does-internet-work Watching:How the Internet Works in 5 Minutes Outline: 互联网通过全球互联的计算机和服务器网络工作,通过标准化协议进行通信。数据被分解成数据包,并使用互联…...
【c++笔试强训】(第三十篇)
目录 爱丽丝的⼈偶(贪⼼构造) 题目解析 讲解算法原理 编写代码 集合(排序) 题目解析 讲解算法原理 编写代码 爱丽丝的⼈偶(贪⼼构造) 题目解析 1.题目链接:登录—专业IT笔试面试备考平…...
微信小程序购物车全选反选功能以及合计
微信小程序基于Vant Weapp的购物车功能实现 1、单选 使用微信小程序原生表单组件checkbox和checkbox-group 注意:checkbox原生不支持bind:change事件,checkbox-group支持 <checkbox-group bindchange"handleCheck"><checkbox val…...
vue-qr在线生成二维码组件(vue2版本)
在对于二维码生成中有许多组件,下面介绍关于自定义比较高的vue-qr组件,能自定义设置背景颜色、背景图片、背景Gif图、实点和空白区的颜色、中心Logo的图片和边距。 依赖下载 注意: 直接npm下载最新版 有些项目可能运行会抱错 这时候你可以降…...
大语言模型技术相关知识-笔记整理
系列文章目录 这个系列攒了很久。主要是前段之间面试大语言模型方面的实习(被拷打太多次了),然后每天根据面试官的问题进行扩展和补充的这个笔记。内容来源主要来自视频、个人理解以及官方文档中的记录。方便后面的回顾。 文章目录 系列文章…...
SCP命令实现Linux中的文件传输
CP命令的主要作用是实现Linux与Linux系统之间的文件传输。 SCP命令时基于SSH协议,所以两台服务器的sshd服务必须处于开启状态,否则无法完成上传与下载操作。 #1.上传文件 scp linux本地文件路径 远程用户名@linux主机地址:远程路径 #2.下载文件 scp 远程用户名@linux主机地址…...
linux环境中后台运行java程序
在生产环境,我们通常需要让java进程后台运行,并且即使会话关闭,进程也依然存在。 使用的命令: nohup java -jar xxx.jar -> aaa.log 2>&1 & 详细介绍下上面这条命令 (1)nohup:…...
Go学习:变量
目录 1. 变量的命名 2. 变量的声明 3. 变量声明时注意事项 4. 变量的初始化 5. 简单例子 变量主要用来存储数据信息,变量的值可以通过变量名进行访问。 1. 变量的命名 在Go语言中,变量名的命名规则 与其他编程语言一样,都是由字母、数…...
在Unity编辑模式下运行Mono中的方法
[ExecuteAlways] 最简单的方法当然是直接给Mono加上[ExecuteAlways]修饰,这样Mono中的Awake,Update等等都可以在编辑模式下按照原本的时机运行。 [ExecuteAlways] public class TestScript : MonoBehaviour {void TestMethod(){Debug.Log("TestMe…...
Y20030028 JAVA+SSM+MYSQL+LW+基于JAVA的考研监督互助系统的设计与实现 源代码 配置 文档
基于JAVA的考研监督互助系统 1.项目描述2. 课题开发背景及意义3.项目功能4.界面展示5.源码获取 1.项目描述 随着高等教育的普及和就业竞争的加剧,越来越多的学生选择继续深造,参加研究生入学考试。考研人数的不断增加,使得考研过程中的学习监…...
MATLAB期末复习笔记(下)
目录 五、数据和函数的可视化 1.MATLAB的可视化对象 2.二维图形的绘制 3.图形标识 4.多子图绘图 5.直方图的绘制 (1)分类 (2)垂直累计式 (3)垂直分组式 (4)水平分组式 &…...
「Mac畅玩鸿蒙与硬件37」UI互动应用篇14 - 随机颜色变化器
本篇将带你实现一个随机颜色变化器应用。用户点击“随机颜色”按钮后,界面背景会随机变化为淡色系颜色,同时显示当前的颜色代码,页面还会展示一只猫咪图片作为装饰,提升趣味性。 关键词 UI互动应用随机颜色生成状态管理用户交互…...
MySql:理解数据库
目录 一、什么是数据库 第一层理解 第二层理解 第三层理解 二、Linux下的数据库 三、基本认识 登录数据库时, mysql -u root -h 127.0.0.1 -P 3306 -p -h指定MySql服务器所在主机,若在本地则为回环地址。-P表示目标主机上MySql服务端口号 一般简单…...
学习笔记051——SpringBoot学习2
文章目录 Spring Boot 原理1、SpringBootConfiguration2、ConfigurationProperties3、ComponentScan4、EnableAutoConfiguration Spring Boot 原理 Spring Boot 可以自动读取配置文件,将项目所需要的组件全部自动加载到 IoC 容器中,包括两部分 开发者自…...
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 …...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...
SQL进阶之旅 Day 22:批处理与游标优化
【SQL进阶之旅 Day 22】批处理与游标优化 文章简述(300字左右) 在数据库开发中,面对大量数据的处理任务时,单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”,深入探讨如何通过批量操作和游标技术提…...
运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.
报错 找到package.json文件 找到这个修改成 "lint": "eslint --fix --ext .js,.vue src" 为elsint有配置结尾换行符,最后运行:npm run lint --fix...
