WMS/AMS 窗口层级结构解析

258 阅读4分钟

通俗易懂解析Android窗口管理机制:WMS与AMS的协同交响曲

大家好,今天我们要揭开Android系统中两个"隐形管家"的神秘面纱——WMS(WindowManagerService)和AMS(ActivityManagerService)。就像高档小区的物业团队一样,他们默契配合,管理着屏幕上每一个窗口的"安家落户"。

一、WMS与AMS的角色定位

WMS(WindowManagerService)—— 建筑设计师

  • 专攻"空间规划":负责窗口的几何布局(位置、大小、层级)
  • 掌管"视觉呈现":控制窗口的动画效果、透明度、截屏权限
  • 维护"硬件交互":与SurfaceFlinger协作完成最终画面合成

AMS(ActivityManagerService)—— 物业经理

  • 专攻"生命周期":管理Activity的启动、暂停、销毁
  • 掌管"任务调度":维护应用栈(Task)和最近任务列表
  • 维护"系统健康":监控应用内存,防止过度消耗

二、窗口层级结构:从底层到顶层的11层"楼层"

Android的窗口层级像一座11层大厦,每层都有特定住户:

	| 楼层  | 典型住户                          | 特性                  |

	|-------|-----------------------------------|-----------------------|

	| 11层  | 启动画面前的Boot动画              | 始终置顶,无视其他窗口 |

	| 10层  | 系统错误对话框(如ANR)            | 强制置顶,穿透锁屏    |

	| 9层   | 系统级悬浮球(如辅助功能按钮)      | 跨应用悬浮            |

	| 8层   | 输入法窗口                        | 自动调整应用布局      |

	| 7层   | 音量调节面板                      | 半透明悬浮            |

	| 6层   | 应用对话框(AlertDialog)          | 模态对话框            |

	| 5层   | 应用Activity窗口                  | 主体内容区域          |

	| 4层   | 壁纸窗口                          | 背景层                |

	| 3层   | 状态栏                            | 系统装饰层            |

	| 2层   | 导航栏(虚拟按键)                | 系统导航层            |

	| 1层   | 锁屏界面                          | 安全验证层            |

三、窗口创建流程:从点击图标到屏幕呈现的六步曲

  1. 用户点击图标:Launcher发送启动Intent
  2. AMS接管:验证权限,创建Task记录,调用startActivityUnchecked
  3. WMS介入:通过addWindow()分配窗口令牌(WindowToken)
  4. Surface分配:创建SurfaceControl,建立与SurfaceFlinger的连接
  5. 布局计算:WMS根据窗口类型和屏幕参数计算最终位置
  6. 绘制合成:SurfaceFlinger收集所有图层进行最终合成

四、源码视角看协作(简化版)

java
	// 伪代码示意Activity启动流程

	public class ActivityManagerService {

	    void startActivity(...) {

	        // 1. 创建Task记录

	        TaskRecord task = new TaskRecord(...);

	        

	        // 2. 调用WMS分配窗口

	        mWindowManager.addWindow(new Session(...), ...);

	    }

	}

	 

	public class WindowManagerService {

	    void addWindow(...) {

	        // 1. 创建WindowToken(房产证)

	        WindowToken token = new WindowToken(...);

	        

	        // 2. 分配Surface(地基)

	        SurfaceControl surface = new SurfaceControl(...);

	        

	        // 3. 计算窗口位置

	        computeWindowPosition(token, surface);

	    }

	}

五、开发者实战指南

场景1:自定义对话框置顶

java
	// 错误方式:直接设置FLAG_SHOW_WHEN_LOCKED可能失效

	Window window = dialog.getWindow();

	window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

	 

	// 正确方式:通过WindowManager设置层级

	WindowManager.LayoutParams params = new WindowManager.LayoutParams(

	    ...,

	    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, // 指定系统层级

	    ...

	);

场景2:沉浸式模式实现

java
	// 关键参数配置

	View decorView = getWindow().getDecorView();

	decorView.setSystemUiVisibility(

	    View.SYSTEM_UI_FLAG_LAYOUT_STABLE

	    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

	    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

	);

场景3:多窗口调试技巧

  • adb shell wm size:查看当前屏幕分辨率
  • adb shell wm list:查看所有窗口信息
  • adb shell dumpsys window windows:获取详细窗口层级

六、高级特性解析

  1. 分屏模式

    • 通过splitScreenCreateAPI创建分屏布局
    • WMS维护两个独立的Task栈
    • 每个窗口获得50%屏幕空间(可配置比例)
  2. 画中画模式

    • 通过enterPictureInPictureMode进入
    • WMS创建特殊类型的WindowToken
    • 窗口层级自动调整为TYPE_PICTURE_IN_PICTURE
  3. 折叠屏适配

    • WMS监听铰链角度变化
    • 动态调整窗口布局(双屏/展开模式)
    • 支持跨屏连续应用体验

七、常见问题Q&A

Q:为什么我的悬浮窗总被系统对话框遮挡?
A:窗口层级设置不当。系统对话框默认使用TYPE_SYSTEM_ALERT(层级6),悬浮窗应使用更高层级(如TYPE_APPLICATION_OVERLAY,层级9)。

Q:如何实现全局弹窗?
A:需要声明SYSTEM_ALERT_WINDOW权限,并设置窗口类型为TYPE_APPLICATION_OVERLAY,但需谨慎使用(可能被系统限制)。

Q:调试窗口层级用什么工具?
A:

  1. 开发者选项中的"显示布局边界"
  2. adb shell dumpsys window windows命令
  3. Layout Inspector工具(Android Studio)

八、未来展望

随着Android系统的演进,窗口管理正在向更智能的方向发展:

  • 动态窗口调整:根据内容自适应窗口大小
  • 空间音频支持:窗口位置与声音方位联动
  • AR窗口管理:虚拟窗口与现实场景融合

理解WMS与AMS的协作机制,就像掌握了Android窗口管理的"空间魔法",它不仅能帮你打造更专业的UI,更能让你在系统级优化中游刃有余。下次当你的应用窗口出现异常时,不妨想想:是不是这两位"隐形管家"的协作需要优化了呢?