20251023 Activity PhoneWindow DocorView ViewRootImpl之间的关系

24 阅读2分钟

Activity是直接与用户发生交互的组件,普通的调用者根本不会去关心PhoneWindow,DocorView 和 ViewRootImpl。PhoneWindow是android里window类的唯一实现,window类像是约束了窗口需要做些什么,而phonewindow则是实实在在的具体实现,这里举一个形象的例子,window好像是一个“相框”的定义,规定了一个相框需要有些什么,比如相框需要有颜色,需要有四条边,而phonewindow则是那个实实在在的木头框子,有具体的载体,而DocorView则更像是相框里的一个内衬,里面规定了上面的留白,状态栏,底部的按钮栏,然后中间的大片空白区域留给Activity去调用setContentView(R.id.xxxx),这里的大片空白区域则是留给Acitivty发挥。

PhoneWindow的详细职责和主要作用:

phonewindow 负责创建整个顶部的 titlebar statusbar 和底部的 navigationbar,然后创建DocorView 用来加载 infalte activity的contentview。

事件分发的机制: 当用户触摸屏幕的时候,activity会将事件第一时间 传达给 PhoneWindow,而phonewindow 则会把事件分发给具体的按钮,例如 菜单键的按下事件。

同时他还是 setcontentview的真正执行者,当activity中设置 setcontentview的时候,activity会第一时间把这个事件传达给PhoneWindow,phonewindow会赶紧实例化一个 DocorView,然后将acitivity里的contentview 赶紧infalte到 docorView中,然后将整个页面渲染出来。

他负责应用您通过requeWindowFeature 或者 getWindow()设置的窗口属性,例如FEATURE_NO_TITLE 隐藏标题栏。

何时创造 ? Activity是在 performLaunchActivity的时候创建的,在startActivity的时候触发的,PhoneWindow则是在Activity的attach方法中创建的,DocorView则是在调用 setcontentview的时候由 PhoneWindow创建。

// 这是一个简化的源码逻辑 public final void attach(Context context, ...) { // ... 其他初始化代码 ... mWindow = new PhoneWindow(this, windowToken); // 在这里创建! // ... 其他初始化代码 ... mWindow.setWindowManager(...); }