跳到主要内容

WMS 窗口管理

问题​

Android 的窗口管理系统是如何工作的?Window、WindowManager、Surface 之间是什么关系?

答案​

核心概念关系​

Window 类型​

类型层级(z-order)示例
Application Window1~99Activity 窗口
Sub Window1000~1999Dialog、PopupWindow
System Window2000~2999Toast、StatusBar、导航栏

层级越高,显示越靠前。

View 绘制流程​

measure:递归遍历 View 树,每个 View 根据 MeasureSpec 计算自身宽高

layout:父 View 根据子 View 的测量结果确定其在父容器中的位置

draw:Canvas 绘制背景、内容(onDraw)、子 View、前景

DecorView 结构​

PhoneWindow
└── DecorView (FrameLayout)
├── StatusBar Background
├── LinearLayout
│ ├── ActionBar / Toolbar
│ └── ContentFrameLayout (android.R.id.content)
│ └── 你的布局 (setContentView)
└── NavigationBar Background

常见面试问题​

Q1: Dialog 必须依附于 Activity 的 Context 原因是什么?​

答案:

Dialog 默认创建的是 Sub Window(子窗口),子窗口必须附属于一个父窗口(Application Window)。Activity 的 Context 中持有 Activity 的 Window Token,Dialog 通过它关联到 Activity 的窗口。如果使用 Application Context,没有 Window Token,会抛出 WindowManager$BadTokenException。

Q2: Window 和 Surface 的区别?​

答案:

  • Window:逻辑概念,代表一个矩形显示区域,由 WMS 管理其位置、大小和层级
  • Surface:实际的图形缓冲区,View 树绘制的内容最终渲染到 Surface 上
  • SurfaceFlinger:系统服务,将所有 Surface 合成为最终的帧输出到屏幕

简单来说,Window 管理"在哪里显示",Surface 管理"显示什么内容"。

Q3: requestLayout 和 invalidate 的区别?​

答案:

方法触发 measure触发 layout触发 draw
requestLayout()✅✅可能
invalidate()❌❌✅
  • 修改 View 尺寸或位置 → requestLayout()
  • 只改变外观(颜色、文字)→ invalidate()

相关链接​