1. Activity中setContentView()发生了什么
setContentView
方法体内是调用的getWindow().setContentView(layoutResID)
,
getWindows()
返回的是一个mWindow
引用,是一个phoneWindow
类型的实例。
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
PhoneWindow.setContentView
的作用
1)installDecor():
初始化DecorView对象()
2)mLayoutInflater.inflate(layoutResID, mContentParent:``LayoutInflate.inflate
最终是调用createViewFromTag
从 xml 生成 View 的,并通过addView
添加到DecorView
对象里面。
但此时
DecorView
还未被添加到Window
中。添加操作需要借助ViewRootImpl
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
ViewRootImpl
的作用
ViewRootImpl
的作用是用来衔接WindowManager
和DecorView
,在 Activity被创建后会通过WindowManager
将DecorView
添加到PhoneWindow
中并且创建ViewRootImpl
实例,随后将DecorView
与ViewRootImpl
进行关联,最终通过执行ViewRootImpl的 performTraversals()
开启整个View树的绘制
2. view 的绘制流程
View
的绘制是从 ViewRootImpl
的 performTraversals()
方法开始,从最顶层的 View(ViewGroup)
开始逐层对每个 View
进行绘制操作
private void performTraversals() {
...............
//measur过程
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...............
//layout过程
performLayout(lp, desiredWindowWidth, desiredWindowHeight);
...............
//draw过程
performDraw();
}
- measure:测量宽高过程,如果是ViewGroup还要在onMeasure中对所有子View进行measure操作。
- layout:用于摆放View在ViewGroup中的位置,如果是ViewGroup要在onLayout方法中对所有子View进行layout操作。
- draw:往View上绘制图像。
3. DecorView何时才被WindowManager真正添加到Window中
ActivityThread
的handleResumeActivity
方法中,首先会调用Activity
的onResume
方法,接着调用Activity的makeVisible()
方法
makeVisible()
中通过WindowManager.addView()
完成了DecorView
的添加和显示两个过程