一句话说透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 是节拍器,错过就掉帧!
相关推荐
androidwork34 分钟前
Android LinearLayout、FrameLayout、RelativeLayout、ConstraintLayout大混战
android·java·kotlin·androidx
每次的天空36 分钟前
Android第十三次面试总结基础
android·面试·职场和发展
wu_android38 分钟前
Android 相对布局管理器(RelativeLayout)
android
李斯维3 小时前
循序渐进 Android Binder(二):传递自定义对象和 AIDL 回调
android·java·android studio
androidwork3 小时前
OkHttp 3.0源码解析:从设计理念到核心实现
android·java·okhttp·kotlin
像风一样自由3 小时前
【001】frida API分类 总览
android·frida
casual_clover3 小时前
Android 之 kotlin 语言学习笔记四(Android KTX)
android·学习·kotlin
移动开发者1号5 小时前
Android 大文件分块上传实战:突破表单数据限制的完整方案
android·java·kotlin
移动开发者1号5 小时前
单线程模型中消息机制解析
android·kotlin
每次的天空8 小时前
Android第十五次面试总结(第三方组件和adb命令)
android