一句话总结:
Window 的机制就像一家快递公司的分拣中心,负责接收包裹(View)、安排派送顺序(层级)、调度货车(Surface),确保每个包裹准时送到用户眼前。
一、Window 的三大核心模块
模块 | 作用 | 比喻 |
---|---|---|
PhoneWindow | Window 的具体实现,管理 DecorView 和功能栏 | 分拣中心的控制台 |
ViewRootImpl | 连接 Window 和系统服务(WMS)的桥梁 | 调度员 + 通信员 |
WindowManager | 添加/删除窗口,设置窗口属性 | 快递公司的前台客服 |
二、Window 的工作流程
1. 创建 Window(开分拣中心)
-
Activity 启动时 :系统创建
PhoneWindow
实例。 -
关键代码:
scss// Activity.java public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); // getWindow() 返回 PhoneWindow }
2. 加载界面模板(标准化包装)
-
DecorView:Window 的根 View,包含系统预设的标题栏、状态栏占位区域。
xml<!-- decor_view.xml 简化结构 --> <LinearLayout> <ViewStub android:id="@+id/title"/> <!-- 标题栏 --> <FrameLayout android:id="@+id/content"/> <!-- 用户内容区域 --> </LinearLayout>
-
用户内容 :通过
setContentView
将布局文件填充到content
区域。
3. 连接系统服务(派调度员对接)
-
ViewRootImpl 创建:
- 绑定 Window 和
WindowManagerService
(WMS)。 - 管理界面绘制、事件分发、VSync 信号接收。
typescript// 伪代码:ViewRootImpl 的纽带作用 public void setView(View view) { mView = view; // DecorView mWindowSession.addToDisplay(...); // 通过 Binder 通知 WMS 添加窗口 }
- 绑定 Window 和
4. 申请画布(租用货车)
-
Surface 创建:
- 由 WMS 分配一块图形缓冲区(Buffer)。
- 通过
Surface
对象交给 App 绘制界面。
-
双缓冲机制:
- Back Buffer:App 正在绘制的新画面。
- Front Buffer:当前显示的画面。
三、事件分发流水线
- 用户点击屏幕 → 硬件层生成触摸事件。
- WMS 查找目标窗口:根据坐标和窗口层级确定哪个 Window 接收事件。
- 事件传递到 ViewRootImpl → 分发给 DecorView。
- DecorView 分发事件 → 层层传递给具体的 View(如按钮)。
css
触摸事件 → WMS → ViewRootImpl → DecorView → Button.onClick()
四、界面绘制流程
-
VSync 信号到来:触发绘制任务。
-
ViewRootImpl 调度 :执行
performTraversals()
(测量、布局、绘制)。 -
绘制命令生成:
- 软件绘制:主线程用 CPU 生成像素数据。
- 硬件加速:转成 GPU 指令(DisplayList)交给 RenderThread。
-
提交到 Surface:将绘制结果写入 Back Buffer。
-
交换 Buffer:VSync 信号时,Back Buffer 和 Front Buffer 瞬间切换。
五、Window 层级管理(Z-Order)
-
三种类型窗口:
类型 层级 示例 应用窗口 1~99 Activity、Dialog 子窗口 1000~1999 PopupWindow 系统窗口 2000+ Toast、状态栏、输入法 -
规则:数值越大越靠前,系统窗口永远盖住应用窗口。
六、Window 的销毁流程
- Activity 退出时 :调用
onDestroy()
。 - ViewRootImpl 通知 WMS:移除窗口。
- Surface 释放:归还图形缓冲区给系统。
七、关键问题解答
1. 为什么 Dialog 不需要新建 Activity?
- 窗口层级不同:Dialog 作为子窗口(层级 1000+)直接覆盖在 Activity 窗口上,共用同一进程资源。
2. 悬浮窗如何实现跨应用显示?
- 系统窗口权限 :申请
TYPE_APPLICATION_OVERLAY
类型,由 WMS 统一管理层级。
3. 界面卡顿的根本原因?
- 主线程阻塞 :
onMeasure/onLayout/onDraw
耗时过长,错过 VSync 信号。 - GPU 过载:复杂图形超出 GPU 处理能力(如过度绘制)。
八、总结口诀
- Window 机制三步走:创建分拣中心 → 对接物流系统 → 调度货车送货。
- 事件分发像快递:WMS 查地址 → ViewRootImpl 派送 → View 签收。
- 绘制流程卡节奏:VSync 是节拍器,错过就掉帧!