要看View的绘制流程首先要看DectorView被添加到Window的过程
handleMessage 方法
![](https://img.haomeiwen.com/i6461854/447ec5c255c6cd6c.png)
handleLaunchActivity方法
![](https://img.haomeiwen.com/i6461854/4925d684d3a50508.png)
handleResumeActivity方法 (这个方法已经和Activity的生命周期关联了)
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);
//删除无用的代码
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);
}
}
}
}
我们看这一句代码
wm.addView(decor, l);
这里的 wm是一个 ViewManager
ViewManager wm = a.getWindowManager();
我们发现ViewManager 是一个接口
![](https://img.haomeiwen.com/i6461854/877b608c33df2516.png)
因为是一个接口所以我们要找到其实现类
ViewManager wm = a.getWindowManager();
![](https://img.haomeiwen.com/i6461854/21ec2a43895cefff.png)
![](https://img.haomeiwen.com/i6461854/39a23206ab9e36a1.png)
我们通过上一篇 setContentView https://www.jianshu.com/p/1c65fd8a1de4 的了解知道 Window有一个唯一的实现类是 PhoneWindow 是因这里的mWindow就是一个Window 所以我们要 找一下 PhoneWindow的 getWindowManager
![](https://img.haomeiwen.com/i6461854/2eb059de6e815dda.png)
我们发现走着走着 又到Window里面了
![](https://img.haomeiwen.com/i6461854/88ef37fa6819810b.png)
![](https://img.haomeiwen.com/i6461854/2ecd30b7db730360.png)
也就是说 wm.addView 其实是 WindowManagerImpl 在addView
wm.addView(decor, l);
WindowManagerImpl 的addView
![](https://img.haomeiwen.com/i6461854/cffa45b4d9c1ebc7.png)
注意这行代码
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
mGlobal 是 WindowManagerGlobal
![](https://img.haomeiwen.com/i6461854/6563050f8eebdc42.png)
为了防止干扰 我删除一些代码
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
ViewRootImpl root;
View panelParentView = null;
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
注意 parentWindow 就是一个Window
![](https://img.haomeiwen.com/i6461854/ed086e4aea0f4718.png)
但为什么追踪到最后也没有看到 dectorView 是如何添加到Window上的呢?谁能告诉我一下呢 兄弟们
网友评论