android 屏幕刷新源码总结

本文深入探讨了Android中视图重绘的过程,从View的invalidate()和requestLayout()出发,详细解析了它们如何触发ViewRootImpl的performTraversals()。在Vsync信号的驱动下,Choreographer负责调度绘制任务,确保绘制操作与Vsync同步,避免不协调问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

view中所有invalidate()/requestLayout()等请求重绘的操作,最终都会表现在ViewRootImpl#performTraversals()中。
从invalidate()入手

invalidate() 
--> ViewRootImpl#scheduleTraversals()
--> ViewRootImpl#Choerographer.postCallback(TraversalsRunnable) // TraversalsRunnable封装了doTraversals()方法,doTraversal()方法又执行了performTraversals()方法。 performTraversals()方法会执行performMeasuer performLayout performDraw等操作,也就是重绘的基本操作。
--> Choerographer#postCallbackDelayed(TraversalsRunnable)
--> Choerographer#postCallbackDelayedInternal(TraversalsRunnable)
--> addCallbackLocked(TraversalsRunnable) // 将Runnable添加到CallbackQueue队列
--> Choerographer#scheduleFrameLocked() --> Choerographer#scheduleVsyncLocked // 添加到队列后,继续请求监听Vsync信号
--> DisplayEventReceiver#nativeScheduleVsyncLocked()

通过以上的代码逻辑,就把view的invalidate()(实际是performTraversals())请求封装到了Runnable中,并加入到CallbackQueue队列中等待执行。同时,因为有重绘操作,所以向底层(SurfaceFlinger)请求监听下一次的Vsync信号。 好让请求的重绘操作执行。

==============================================================
底层发出Vsync信号时的刷新过程:

SurfaceFlinger.Vsync 
--> DisplayEventReceiver.dispatchVsync
--> FrameDisplayEventReceiver.onSync & run
--> Choreographer.doFrame()
--> Choreographer.doCallbacks()
--> Choreograpger.extraDueCallbackLocked() //去除之前存放的Runnable并执行

1、ViewRootImplViewRootImpl怎来的,大家可以看看ActivityThread里面的handleResumeActivity,抛开anr这些系统的窗口等,理论上一个APP应该是一个ViewRootImpl在WindowManagerGlobal的addView会

root = new ViewRootImpl(view.getContext(), display);       
root.setView(view, wparams, panelParentView);

也就是说, ViewRootImpl的mView其实是DecorView.而DecorView是一个activity中最外层的view了,其实是继承的FrameLayout。
而对于View不论是Invalidate还是requestlayout,这些重绘开始的地方都是ViewRootImpl的scheduleTraversals,在scheduleTraversals中,

mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,mTraversalRunnable, null);

有这样一行代码,这个mTraversalRunnable就是调用了View measure,layout,draw的非常经典的performTraversals方法。
而postCallback中做的事情主要就是根据时间看这个啥时候执行,如果要立即执行了就添加到一个callback队列中然后去请求VSYNC(这里只考虑有VSYNC的场景)。如果不需要立即执行就sendmessage做一个队列排队去。
Choreographer是对VSYNC做了监听的,当有VSYNC消息的时候会执行onVsync,最终走到Choreographer的doFrame,在这里会将从callback队列中取出runnable进行绘制。
所以对于当用户手动去invalidate,或者requestlayout的情况,还是会通过Choreographer对这些请求做排队处理,所有绘制的地方都会等待VSYNC的消息回调再去做相应的绘制。所以就不会出现,用户要求去绘制,但是这个时机和VSYNC不同步的问题了。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值