ActivityThread中的handleLaunchActivity方法中,有performLaunchActivity
performLaunchActivity() {
// 伪代码
Activity activity = new Activity();
activity.attatch(); // 创建了Phonewindow,获得了WindowMananger服务
activity.setTheme(); // 设置Theme
mInstrumentation.callActivityOnCreate(); // 调用了activity.performCreate()
activity.performStart(); //通过mInstrumentation调用onStart
}
Activity的调用setContentView:
setContentView() {
getWindow().setContentView(); // 上面已经创建好了PhoneWindow
}
PhoneWindow的setContentView:
setContentView() {
installDecor(); // 创建了DecorView
mLayoutInflater.inflate(layoutResID, mContentParent); // 将activity的布局放入mContentParent中
}
PhoneWindow的installDecor:
installDecor() {
mDecor = generateDecor(); // new了一个DecorView,并设置了window,就是上面的phoneWindow
mContentParent = generateLayout(mDecor); // 得到mContentParent
}
PhoneWindow的generateLayout
generateLayout() {
// 确定layoutResource
mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
}
DecorView的onResourcesLoaded
onResourcesLoaded() {
final View root = inflater.inflate(layoutResource, null);
addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); // 添加View
mContentRoot = (ViewGroup) root; // 设置mContentRoot
}
那么ViewRootImpl在哪里呢?最后发现,View里面有一个方法getViewRootImpl,用于获取
public ViewRootImpl getViewRootImpl() {
if (mAttachInfo != null) {
return mAttachInfo.mViewRootImpl;
}
return null;
}
在WindowManagerGlobal的addView方法里,new了一个ViewRootImpl
WindowManagerImpl implements WindowManager
,其中有一个成员变量,WindowManagerGlobal,它的addView:
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
是在哪里调用的呢?搜索发现很多地方都在调用(但其实大部分搜索结果是View的addView方法,而不是wm的),比如:
1.ActivityThread里handleResumeActivity有调用
wm.addView(decor, l); // 很显然是resume的时候嘛
2.Activity的makeVisible方法有调用
ActivityRecord.java
ActivityStack.java
ActivityStackSupervisor.java
上面这几个类里都有用到setVisible,具体需要再排查,或者这第二种情况用的本来就不多,通常情况还是通过第一种情况调用的wm的addView
我的理解是ViewRootImpl牵扯到一些交互,在显示给用户的时候,应该创建出来了