跳到主要内容

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()

相关链接