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方法绘制,跟丢帧没有关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值