View从调用invalidate到draw经历的主要流程

话不多说,先上时序图。

 

View调用invalidate()后到执行它的draw()方法主要经历了如图所示的流程,这里面主要涉及到了View、ViewRootImpl、MessageQueue(Handler这一整套)、Choreographer、DisplayEventReceiver这几个模块,其实这里的每一个模块都是比较复杂的,本文从View调用invalidate()到执行它的draw()方法这一流程视角分析一下这些模块的联系。

android的视图是View的树状结构。View调用invalidate()方法后,在view hierarchy内向上递归调用,一直调用到ViewRootImpl中的invalidate()方法。

ViewRootImpl是view hierarchy上最上的一个,它是一个ViewParent,主要负责view与WindowManager之间的连接。ViewRootImpl在scheduleTraversals方法中,首先往MessageQueue里面发送一个synchronization barrier消息。MessageQueue在执行到ynchronization barrier消息时会阻塞它后面的同步消息的执行,只能执行它后面的异步消息,DisplayEventReceiver收到Vsync信号后则往MessageQueue里面发送一个异步消息,ViewRootImpl在执行doTraversal的时清除之前往MessageQueue里面发送的synchronization barrier消息。通过这种方式可以尽快调用Vsync信号触发的绘制消息,减少UI绘制的卡顿。

android的主线程是基于消息的,所以所有主线程的代码都是由MessageQueue里面的消息直接或者间接触发执行的。在View调用invalidate()到执行它的draw()方法这个流程中,往MessageQueue里面发送了synchronization barrier消息和触发Choreographer执行doFrame的异步消息。

Choreographer执行postCallback后向DisplayEventReceiver请求Vsync信号,到此时刻整个invalidate的调用流程已结束,等待Vsync信号的到来。DisplayEventReceiver收到Vsync信号后,往MessageQueue里面发送一个异步消息,在执行这个消息的时候执行Choreographer的doFrame方法,在doFrame里面先后执行输入事件的回调,动画的回调,绘制UI的回调、 Commit 相关回调。

DisplayEventReceiver通过 BitTube(本质是一个 socket pair),来传递和请求 Vsync 事件,当 SurfaceFlinger 收到 Vsync 事件之后,通过 appEventThread 将这个事件通过 BitTube 传给 DisplayEventReceiver ,DisplayEventReceiver通过 BitTube 的接收端监听到 Vsync 事件之后,回调 Choreographer.FrameDisplayEventReceiver.onVsync ,在onSync方法中往MessageQueue中enqueue一个异步消息,开始一帧的绘制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值