一句话说透Android里面的Window的内部机制

一句话总结

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 添加窗口
    }

4. 申请画布(租用货车)

  • Surface 创建

    • 由 WMS 分配一块图形缓冲区(Buffer)。
    • 通过 Surface 对象交给 App 绘制界面。
  • 双缓冲机制

    • Back Buffer:App 正在绘制的新画面。
    • Front Buffer:当前显示的画面。

三、事件分发流水线

  1. 用户点击屏幕 → 硬件层生成触摸事件。
  2. WMS 查找目标窗口:根据坐标和窗口层级确定哪个 Window 接收事件。
  3. 事件传递到 ViewRootImpl → 分发给 DecorView。
  4. DecorView 分发事件 → 层层传递给具体的 View(如按钮)。
css 复制代码
触摸事件 → WMS → ViewRootImpl → DecorView → Button.onClick()

四、界面绘制流程

  1. VSync 信号到来:触发绘制任务。

  2. ViewRootImpl 调度 :执行 performTraversals()(测量、布局、绘制)。

  3. 绘制命令生成

    • 软件绘制:主线程用 CPU 生成像素数据。
    • 硬件加速:转成 GPU 指令(DisplayList)交给 RenderThread。
  4. 提交到 Surface:将绘制结果写入 Back Buffer。

  5. 交换 Buffer:VSync 信号时,Back Buffer 和 Front Buffer 瞬间切换。


五、Window 层级管理(Z-Order)

  • 三种类型窗口

    类型 层级 示例
    应用窗口 1~99 Activity、Dialog
    子窗口 1000~1999 PopupWindow
    系统窗口 2000+ Toast、状态栏、输入法
  • 规则:数值越大越靠前,系统窗口永远盖住应用窗口。


六、Window 的销毁流程

  1. Activity 退出时 :调用 onDestroy()
  2. ViewRootImpl 通知 WMS:移除窗口。
  3. Surface 释放:归还图形缓冲区给系统。

七、关键问题解答

1. 为什么 Dialog 不需要新建 Activity?

  • 窗口层级不同:Dialog 作为子窗口(层级 1000+)直接覆盖在 Activity 窗口上,共用同一进程资源。

2. 悬浮窗如何实现跨应用显示?

  • 系统窗口权限 :申请 TYPE_APPLICATION_OVERLAY 类型,由 WMS 统一管理层级。

3. 界面卡顿的根本原因?

  • 主线程阻塞onMeasure/onLayout/onDraw 耗时过长,错过 VSync 信号。
  • GPU 过载:复杂图形超出 GPU 处理能力(如过度绘制)。

八、总结口诀

  • Window 机制三步走:创建分拣中心 → 对接物流系统 → 调度货车送货。
  • 事件分发像快递:WMS 查地址 → ViewRootImpl 派送 → View 签收。
  • 绘制流程卡节奏:VSync 是节拍器,错过就掉帧!
相关推荐
子非衣3 小时前
MySQL修改JSON格式数据示例
android·mysql·json
openinstall全渠道统计7 小时前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
双鱼大猫7 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫7 小时前
一句话说透Android里面的查找服务
android
双鱼大猫7 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫7 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
双鱼大猫8 小时前
一句话说透Android里面的为什么要设计Window?
android
双鱼大猫8 小时前
一句话说透Android里面的主线程创建时机,frameworks层面分析
android
苏金标9 小时前
android 快速定位当前页面
android