setContentView 流程
- Activity -> setContentView
开发者设置入口 - PhoneWindow -> setContentView
mWindow 在 attach 时初始化为 PhoneWindow,同时PhoneWindow也是Window唯一的实现类 - PhoneWindow -> installDecor
这一步的作用是 初始化DecorView, 把DecorView填充到 mContentParent;
generateDecor
用于生成DecorViewgenerateLayout
用于设置应用系统属性和特别的布局- DecorView - >
onResourcesLoaded
方法就是把上一步生成的layout添加到DecorView中
- 上一步就是为了获取
mContentParent
, 回到setContentView
中,通过inflate
方法把layoutResId
添加到mContentParent
中
如果是使用 AppCompatActivity, 还会多一步设置 mSubDecor。 它是在DecorView 上又加了一层,主要用于设置主题
UI 绘制流程
参考 onCreate和onResume为什么不能直接获取宽高.md
- ActivityThread -> handleLaunchActivity -> performLaunchActivity
performLaunchActivity
中主要是做了3件事情:
- 创建了
Activity
对象 - 调用
attach
, 初始化Window
和WindowManager
- 调用了
onCreate
方法。 - 上面的 setContentView
- ActivityThread -> handleResumeActivity
- 执行 Activity 的 onResume 方法
- 执行
wm.addView(decor, l);
, 把之前的 DecorView 添加到视图中,开始执行布局的绘制流程。
- 最后会走到布局管理器中
ViewRootImpl
的performTraversals
方法中
private void performTraversals() {……// 【关键点1】分发mAttachInfohost.dispatchAttachedToWindow(mAttachInfo, 0);……//【关键点2】开始测量performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);……//【关键点3】开始布局performLayout(lp, mWidth, mHeight);……// 【关键点4】开始绘制performDraw();……}
此时UI绘制流程基本结束,页面也展示出来了