通俗易懂解析WindowManager

177 阅读3分钟

这篇文章主要围绕 Android 中的 WindowManager 体系展开,从源码角度剖析了 Window 相关的核心知识,以下是用通俗语言对其内容的梳理:

一、WindowManager 体系的三大核心角色

  1. Window(窗口)
    就像一个透明的 “容器”,用来装需要显示的界面(View),比如 Activity 的界面。它是抽象类,具体实现是PhoneWindow,每个 Activity 都有一个对应的 PhoneWindow。
  2. WindowManager(窗口管理器)
    相当于 App 和系统之间的 “中间人”,是一个接口,实现类是WindowManagerImpl。它负责管理 Window 的添加、更新和删除,但实际干活的是系统服务。
  3. WindowManagerService(WMS,窗口管理服务)
    系统中的 “大管家”,运行在系统进程里,通过 Binder 和 App 通信。真正执行 Window 的添加、显示层级控制等操作,比如确定哪个窗口显示在最前面。

二、关键问题解析

1. Window 和 Activity、WindowManager 如何建立关系?

  • Activity 创建时:在attach()方法中,Activity 会 new 一个PhoneWindow,并把自己作为上下文传进去,这样 Window 就和 Activity 绑定了。
  • WindowManager 的关联:Window 通过setWindowManager()方法获取WindowManagerImpl实例,这个实例会持有 Window 的引用,方便后续操作。

2. Window 如何和界面(View)关联?

  • Activity 调用setContentView()时,PhoneWindow 会创建一个DecorView(窗口的根视图),并把布局文件解析后的 View 添加到 DecorView 中。这样,Window 就和具体的界面内容绑定了。

3. Window 的属性:类型、层级、标志等

  • 窗口类型(Type)
    分为三类:

    • 应用程序窗口(如 Activity,Type 值 1~99);
    • 子窗口(如 PopupWindow、Dialog,Type 值 1000~1999);
    • 系统窗口(如状态栏、Toast,Type 值 2000~2999)。
      类型值越大,窗口越靠上(比如系统窗口会覆盖应用窗口)
  • 层级关系(Z-Order)
    窗口像叠纸一样排列,Z 轴垂直于屏幕。类型值决定层级,系统窗口 > 子窗口 > 应用程序窗口。同类型窗口的层级由 WMS 根据情况调整。

  • 窗口标志(Flag)
    控制窗口的行为,比如:

    • FLAG_KEEP_SCREEN_ON(窗口可见时屏幕常亮);
    • FLAG_FULLSCREEN(全屏显示,隐藏状态栏等);
    • FLAG_NOT_TOUCHABLE(窗口不可点击)。
  • 软键盘模式
    控制软键盘弹出时的界面处理,比如SOFT_INPUT_ADJUST_RESIZE(键盘弹出时界面 Resize)、SOFT_INPUT_ADJUST_PAN(界面上移让输入框可见)。

4. View 如何显示到屏幕上?

  • 添加流程
    App 通过WindowManager.addView()添加 View,实际由WindowManagerGlobal处理,它会创建ViewRootImpl(管理 View 的绘制和与 WMS 通信)。最终通过 Binder 调用 WMS 的addToDisplay(),WMS 分配 Surface 并确定层级,SurfaceFlinger 将多个 Surface 合并后显示到屏幕。
  • 删除流程
    通过WindowManager.removeView()触发,ViewRootImpl会销毁资源,通过 WMS 的removeWindow()从系统中移除窗口。

三、总结

文章从源码出发,讲解了 WindowManager 体系的核心组件、Window 与 Activity/View 的绑定过程、窗口属性的作用,以及 View 添加和删除的底层流程。重点是理解 WMS 作为系统服务如何管理所有窗口的显示层级和状态,而 WindowManager 是 App 操作窗口的接口,Window 则是承载界面的容器。下篇将继续深入 WMS 内部的窗口操作逻辑。