ActivityThread#handleResumeActivity()->WindowManagerImpl#addView()->WindowManagerGlobal#addView()->ViewRootImpl(view.getContext(),Display)。
构造函数中会将第一个参数赋值给ViewRootImpl的全局变量mContext。handleResumeActivity传入的View对象是Window#mDecor,所以view.getContext()返回的就是DecorView所指的Activity实例。
择一部分构造函数中的代码如下:
mWindowSession = WindowManagerGlobal.getWindowSession();
mWindow = new W(this);
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
第一句mWindowSession赋值为WindowManagerGlobal.getWindowSession(),其返回值为一个Session对象,Session的实例化在WMS进程中进行的,本应该中有一个Session的代理对象,所以可以通过Session主要调用WMS中一些方法。
第二、三句中的W继承于IWindow.Stub,后者继承于Binder又实现了IWindow接口,因此这个W是可以IPC的。第三句中将mWindow赋值给了View.AttachInfo中的mWindow对象,将mWindowSession赋值给了mSession变量。
与构造函数调用时机相同,并且View参数也相同。所以ViewRootImpl中的mView指的是该ViewRootImpl指依赖的Activity中的DecorView。因此它可以通过调用mView来绘制一个Acitivity组件的UI。
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
//略
requestLayout();
//略
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
}
//略
}
}
}
而requestLayout->scheduleTraversals()->Choreographer#postCallback()->……->postCallbackDelayedInternal()->scheduleFrameLocked()->scheduleFrameLocked(),它发一个what为MSG_DO_FRAME的msg->doFrame()。
在这个过程中,有必要跟踪一下scheduleTraversals()的参数,在postCallbackDelayedInternal()之前,都是正常传递的。postCallbackDelayedInternal()如下:
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {//前两个参数就是scheduleTraversals()中的参数,token为Null,delayMills为0
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
//上一步将三个参数封装成CallbackRecord对象,并通过队列存储
if (dueTime <= now) {//由于delayMills为0,所以走这一步
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
到doFrame()时,有这么一句话:
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
其中第一个参数就是scheduleTraversals()的第一个参数,而doCallBacks()中又会调用CallbackRecord#run()。 public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);
} else {
((Runnable)action).run();
}
}
因此到这里之后,会执行scheduleTraversals()中的第二个参数。其第二个参数->doTraversal()->performTraversals(),在这个方法中会执行View的measure,layout与draw。