Activity,Window,DecorView,ViewRootImpl

在 Activity 中进行一些窗口类的操作时,有时操作 Activity,有时操作 Window,有时又操作 DecorView,脑子很乱。在这里梳理一下 Activity,Window,DecorView,ViewRootImpl 之间的关系。

Activity 管理生命周期,通过 Window 显示 View。
Window 负责创建与管理 DecorView,通过 WindowManager,使用自己的 WindowManager.LayoutParams mWindowAttributes 显示自己的 DecorView。
WindowManagerGlobal 创建 ViewRootImpl,ViewRootImpl 负责与 WMS,SF 交互,显示,更新 View。

PhoneWindow 创建 DecorView:

DecorView 是 Activity 所拥有的 View 树的顶层 View。它是在 PhoneWindow 的构造函数中创建的。

PhoneWindow 构造函数

Activity.setContentView

每次创建 Activity 时都要使用的 setContentView。其实就是将 View 添加为 DecorView 的 mContentParent ( id == Window.ID_ANDROID_CONTENT ) 的子 View。
要获取这个 mContentParent,可以使用

getWindow().getDecorView().findViewById(Window.ID_ANDROID_CONTENT)

Window 布局属性如何生效

Window 内部有 WindowManager.LayoutParams  mWindowAttributes 成员变量。

Window 的 Attributes

通过 Window 更改的布局属性,最终就是通过这个 mWindowAttributes 生效的。
举个例子,调用 Window 的setSoftInputMode:

Window.setSoftInputMode

设置属性后,调用 dispatchWindowAttributesChanged 生效:

Window.dispatchWindowAttributesChanged

对于 Activity 的 PhoneWindow,mCallback 就是 Activity:

Activity implements Window.Callback

最终,Activity 通过 WindowManager 更新 LayoutParams:

Activity.onWindowAttributesChanged

ViewRootImpl

ViewRootImpl 负责与 WMS,SF 交互。

ViewRootImpl 是在 addView 时,在 WindowManagerGlobal 中创建的。所以,对于 Activity 和 Window,ViewRootImpl 其实是不可见的:

WindowManagerGlobal.addView

Window vs PopupWindow

综上,向 WMS 添加 View,从 app 的角度看,Window 和 DecorView 不是必须的。Window 只是方便对 View 进行管理,除了 Activity,也可以在别的地方使用 Window,比如 Dialog 就是通过 Window 添加 View 的。
同时,Window 也不是必须的。比如 PopupWindow,自己作为 Window,没有使用到 Window。同时也没有使用 DecorView,而是使用自己的 PopupDecorView:

PopupWindow.mDecorView

PopupWindow 使用 WindowManger 添加 View:

PopupWindow.invokePopup

你可能感兴趣的:(Activity,Window,DecorView,ViewRootImpl)