ViewRootImpl位于视图层次结构的顶部,负责View和WindowManager之间的通信。
ViewRootImpl关联了多个类和接口,IWindowSession、Choreographer及其FrameCallback接口等。IWindowSession用于客户端和WindowManagerService之间进行窗口管理操作的接口,允许ViewRootImpl与WindowManagerService进行通信,执行如添加、删除、更新窗口等操作。
scheduleTraversals
scheduleTraversals()方法负责将一次视图遍历(traversal)排期到其调度计划中,但并不会立即执行遍历操作。方法被许多操作所调用,比如当视图的大小、位置等属性发生变化时,或者当调用requestLayout()、invalidate()等方法时,都会触发scheduleTraversals()。作用是将视图的测量、布局和绘制操作(即遍历操作)放入待执行队列中,并注册一个底层的刷新信号监听器。
public void invalidate(boolean invalidateCache) {
invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
}
void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache, boolean fullInvalidate) {
...
// Propagate the damage rectangle to the parent view.
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
if (p != null && ai != null && l < r && t < b) {
final Rect damage = ai.mTmpInvalRect;
damage.set(l, t, r, b);
//调用父容器的方法,向上传递事件
p.invalidateChild(this, damage);
}
...
}
public final void invalidateChild(View child, final Rect dirty) {
.....
ViewParent parent = this;
do {
View view = null;
if (parent instanceof View) {
view = (View) parent;
}
if (drawAnimation) {
if (view != null) {
view.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
} else if (parent instanceof ViewRootImpl) {
((ViewRootImpl) parent).mIsAnimating = true;
}
}
// If the parent is dirty opaque or not dirty, mark it dirty with the opaque
// flag coming from the child that initiated the invalidate
if (view != null) {
if ((view.mViewFlags & FADING_EDGE_MASK) != 0 && view.getSolidColor() == 0) {
opaqueFlag = PFLAG_DIRTY;
}
if ((view.mPrivateFlags & PFLAG_DIRTY_MASK) != PFLAG_DIRTY) {
view.mPrivateFlags = (view.mPrivateFlags & ~PFLAG_DIRTY_MASK) | opaqueFlag;
}
}
//调用ViewGrup的invalidateChildInParent,如果已经达到最顶层view,则调用ViewRootImpl的invalidateChildInParent。
parent = parent.invalidateChildInParent(location, dirty);
if (view != null) {
// Account for transform on current parent
Matrix m = view.getMatrix();
if (!m.isIdentity()) {
RectF boundingRect = attachInfo.mTmpTransformRect;
boundingRect.set(dirty);
m.mapRect(boundingRect);
dirty.set((int) Math.floor(boundingRect.left),
(int) Math.floor(boundingRect.top),
(int) Math.ceil(boundingRect.right),
(int) Math.ceil(boundingRect.bottom));
}
}
} while (parent != null);
}
}
当VSYNC信号到来时(VSYNC信号是Android系统中用于同步屏幕刷新的信号),系统会从待执行队列中取出对应的scheduleTraversals()操作,并将其加入到主线程的消息队列中。然后,主线程会从消息队列中取出并执行这个操作,进而触发视图的测量、布局和绘制流程。
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
//这里判断,当前执行的线程是否是创建该Choreographer的线程,如果是直接执行。否则通过handler 发送到 创建该Choreographer的线程去执行。
if (isRunningOnLooperThreadLocked()) {
scheduleVsyncLocked();
} else {
//这条message 最后处理还是调用到了scheduleVsyncLocked方法
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
final long nextFrameTime = Math.max(
mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
if (DEBUG_FRAMES) {
Log.d(TAG, "Scheduling next frame in " + (nextFrameTime - now) + " ms.");
}
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
}
public void scheduleVsync() {
if (mReceiverPtr == 0) {
Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event " + "receiver has already been disposed.");
} else {
nativeScheduleVsync(mReceiverPtr);
}
}
在这个过程中,performTraversals()方法会被调用。方法会执行实际的测量、布局和绘制操作。首先会调用measureHierarchy()方法进行测量,然后调用performLayout()方法进行布局,最后调用draw()方法进行绘制。这些操作会按照顺序执行,以确保视图能够正确地显示在屏幕上。最终通过nativeScheduleVsync()原生方法通知屏幕进行绘制。
performTraversals
performTraversals()方法负责启动视图的测量(measure)、布局(layout)和绘制(draw)流程。当需要创建视图、视图参数改变或界面需要刷新时,可能会从根视图DecorView开始重新进行测量、布局和绘制,这时就会调用到performTraversals()方法。
private void performTraversals() {
...
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
performLayout(lp, desiredWindowWidth, desiredWindowHeight);
...
performDraw();
}
void doTraversal() {
//防止重入
if (mTraversalScheduled) {
mTraversalScheduled = false;
//移除同步屏障
mHandler.getLooper().getQueue()
.removeSyncBarrier(mTraversalBarrier);
performTraversals();
}
}
图片
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void scheduleTraversals() {
if (!mTraversalScheduled) {
//移除同步屏障
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
}
}
void unscheduleTraversals() {
mChoreographer.removeCallbacks(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
}
}
public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
}
public void postCallbackDelayed(int callbackType,
Runnable action, Object token, long delayMillis) {
...
postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
....
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
//把 任务添加到了mCallbackQueues 回调里面去,等待回调执行。
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
//now=0 ,走进scheduleFrameLocked()方法内
if (dueTime