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

Android编舞者类Choreographer小结

Android编舞者类Choreographer小结

作用

编舞者类的作用主要是控制绘制节奏,用于发起一次vsync垂直同步信号的监听,当垂直同步信号来的时候会回调注册的Runnable或者FramCallback

Choreographer对象获取

Choreographer对象是通过它的getInstance方法获取实例,虽然看名字是单例,但是它是保存在ThreadLocal中,每个线程都会有一个唯一的实例,而不是全局单例

同步信号请求过程

  1. ViewRootImplscheduleTraversals方法中,会先设置一个同步屏障,然后调用编舞者类的postCallback方法发起一次请求同步信号

    1. postCallback和postFrameCallback的区别主要在于请求的垂直同步信号的类型不同;postFrameCallback请求的类型是animation回调的对象类型是FrameCallback,而postCallback可以自定义传入任何类型的垂直同步信号,执行的回调对象类型是Runnable
  2. 编舞者类会把这个Callback根据类型和时间的先后顺序保存到队列中,队列的实现方式是单链表结构;Callback的类型有五种:input、animation、inserts_animation、traversal、commit

  3. 然后判断当前线程是否主线程,如果不是的话则通过Handler发送消息到主线程去执行,如果是主线程,则立刻调用native方法发起一次同步信号请求

  4. 当垂直同步信号来的时候,会回调响应的方法,最后会调用doFrame方法去处理垂直同步信号

  5. 在doFrame方法里面

    1. 先根据当前时间减去垂直同步信号的时间计算时间差,判断有没有跳帧,如果有跳帧并且超过30帧,则打印Log,并且会重新计算当前帧的绘制时间;

    2. 如果计算后当前帧的时间小于上一次帧绘制时间,则会重新发起一次垂直同步信号请求

    3. 接着从五个队列中,依次取出各个Callback并调用相应方法,Runnable调用run方法,FrameCallback调用doFrame方法

  6. 接着ViewRootImpl就开始调用doTraversal->performTraversal->performMeasure->performLayout->performDraw开始绘制

问答

  • Q: 我们都知道Android的刷新频率是60帧/秒,这是不是意味着每隔16ms就会调用一次onDraw方法?

A: 不是,只有当界面需要刷新,并且编舞者请求的垂直同步信号到达时才会调用

  • Q: 如果界面不需要重绘,那么还16ms到后还会刷新屏幕吗?

    A: 会的,但是刷新的是旧的数据

  • Q: 我们调用invalidate()之后会马上进行屏幕刷新吗?

    A: 不会的,需要等待下一次垂直同步信号才会刷新

  • Q: 我们说丢帧是因为主线程做了耗时操作,为什么主线程做了耗时操作就会引起丢帧

    A:因为垂直同步信号是由底层发出的,而且发出的时间间隔是一样的,如果主线程做了耗时操作,会导致编舞者类接收到垂直同步信号的时间比较晚,界面就不能及时刷新,从而引起丢帧和界面卡顿

  • Q: 如果在屏幕快要刷新的时候才去OnDraw()绘制,会丢帧吗?

    A: 不会,屏幕刷新也是跟着垂直同步信号走的,当垂直信号到了的时候才会触发onDraw方法绘制,跟丢帧没有关系

http://www.lryc.cn/news/44837.html

相关文章:

  • 大专升本科难度大吗 需要考哪些科目
  • 考研复试-英语问答+解答
  • python 文件相关的操作 常用函数(读文件、写文件、文件的追加内容、修改文件内容、复制文件、按行读取文件、with open) json文件的读取
  • python 系列 06 -生成及解析二维码
  • 2023第二届中国绿色钢铁国际峰会
  • java 高考志愿填报系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目
  • 机器学习 vs 深度学习:了解两者的异同
  • 流行的 DAW编曲软件FL Studio 21 有什么新功能?
  • 【Java】抽象类和接口
  • Lora:Low-Rank Adapation of Large Language models
  • 洛谷-P8466 [Aya Round 1 A] 幻想乡扑克游戏
  • HBase性能优化方法总结
  • Linux基础内容(16)—— 文件系统
  • Vue自定义事件
  • Java SE 基础 (6) 第一个Java程序
  • P1004 [NOIP2000 提高组] 方格取数
  • Leetcode.1024 视频拼接
  • 20个华为路由器常用的Python脚本,网工写自动化脚本时候可以参考!
  • 【kubernetes云原生】k8s资源管理命令与Namespace使用详解
  • String源码深度刨析
  • FreeRTOS - 消息队列
  • 怎样正确做 Web 应用的压力测试?
  • php mysql大学生求职招聘资源信息网zkfdzkf67a8
  • 2023上海市“星光计划”职业院校技能大赛 网络安全竞赛试题任务书
  • Spring事务源码:创建代理类
  • java14 使用增强的模式匹配切换表达式
  • python【正则表达式】
  • Ubuntu常见系统问题解决方式
  • C/C++中的虚拟内存
  • Qt C++与Python混合编程:补充错误