1.在ActivityThread#handleLaunchActivity():
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
activity.attach(...)方法中,创建PnoneWindow,代码如下:
//... ...
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
//... ...
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
mWindow.setColorMode(info.colorMode);
此时还不会创建DecorView,在onCreate()中调用setContentView时,就会调用getWindow().setContentView,此时在PhoneWindow#setContentView()方法中调用installDecor()方法去创建一个DecorView。如果没有调用setContentView,那么installDecor()方法将延迟到handleResumeActivity()中,Activity.getWindow.getDecor()时,PhoneWindow#getDecor()方法如下:
@Override
public final View getDecorView() {
if (mDecor == null || mForceDecorInstall) {
installDecor();
}
return mDecor;
}
2.在ActivityThread#handleResumeActivity():
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// Normally the ViewRoot sets up callbacks with the Activity
// in addView->ViewRootImpl#setView. If we are instead reusing
// the decor view we have to notify the view root that the
// callbacks may have changed.
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
// The activity will get a callback for this {@link LayoutParams} change
// earlier. However, at that time the decor will not be set (this is set
// in this method), so no action will be taken. This call ensures the
// callback occurs with the decor set.
a.onWindowAttributesChanged(l);
}
}
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
}
将PhoneWindow的decorView取出来,使用Activity.mWindowManager以decorView为参数添加窗口。
最终WindowManagerImpl将调用WindowManagerGlobal#addView(...),在WindowManagerGlobal#addView(...)中将创建ViewRootImpl,最后确立ViewRootImpl、View、LayoutParams三元组。最后使用ViewRootImpl#setView(...),在setView()中通过IWindowSession.addToDisplay(IWindow,LayoutParams,InputChannel,...)正式向WMS注册一个窗口,并得到了一个监听输入事件的管道,在接下来的遍历控件树的布局窗口阶段通过IWindowSession.relayoutWindow(Surface)才正在获得一个窗口,即可以通过得到的Surface,遍历控件树的绘制阶段在Surface上绘图,并最终提交到SurfaceFlinger,这样窗口内容就可以显示了