安卓的GUI

291 阅读48分钟

在 Android 系统中,窗口管理(尤其是多应用、多窗口、弹窗等场景)由 WindowManagerService (WMS) 统一协调,其核心职责是管理所有窗口的层级(Z-Order)、位置、尺寸、焦点和生命周期。以下是其管理机制的分层解析:


1. 窗口的类型与层级(Z-Order)

(1) 窗口类型分类

类型示例层级范围说明
应用窗口Activity、Dialog1~99应用主窗口及其子窗口(如弹窗)。
子窗口PopupWindow、Spinner1000~1999必须依附于父窗口(如 Activity),层级由父窗口决定。
系统窗口状态栏、导航栏、Toast、输入法2000~2999全局可见,独立于应用窗口,由系统进程管理。
系统警报窗口来电提醒、系统级弹窗3000~3999最高优先级,覆盖所有其他窗口。
  • Z-Order 规则:值越大,层级越高,窗口越靠前显示(覆盖低层级窗口)。

(2) 层级管理关键点

  • 窗口的添加顺序:同类型窗口按添加顺序叠加,后添加的层级更高。
  • 动态调整:可通过 WindowManager.LayoutParams.z 属性手动调整层级(需权限)。

2. 多应用窗口的管理

(1) 多任务与窗口堆栈

  • Activity 堆栈(TaskStack):每个应用的 Activity 按任务(Task)组织,WMS 维护全局的窗口堆栈。
  • 窗口归属:每个窗口关联到对应的应用进程,WMS 通过 Binder IPC 管理跨进程通信。
  • 焦点窗口:WMS 根据窗口层级和用户交互(如点击)确定焦点窗口,输入事件(触摸、按键)只会分发到焦点窗口。

(2) 多窗口模式

模式说明
分屏模式两个应用窗口并列显示,WMS 计算各自尺寸并限制触摸事件到活动窗口。
画中画(PiP)视频小窗口浮动在其他窗口之上,WMS 管理其位置和焦点。
自由窗体模式允许窗口自由调整大小(如平板模式),WMS 动态计算布局。

3. 应用内多页面与弹窗管理

(1) Activity 与 Window 的关系

  • 单 Activity 多窗口:一个 Activity 可关联多个窗口(如主窗口 + 多个 Dialog)。
  • 窗口切换:Activity 切换时,旧窗口销毁,新窗口添加到窗口堆栈。

(2) 弹窗的管理

  • Dialog:作为子窗口依附于 Activity 窗口,层级高于 Activity 内容但低于系统窗口。
  • PopupWindow:必须指定锚点 View,层级由父窗口决定。
  • Toast:属于系统窗口,层级较低(通常不会遮挡输入法)。

弹窗显示流程

  1. 创建窗口:通过 WindowManager.addView() 添加弹窗视图。
  2. 层级计算:WMS 根据弹窗类型和父窗口确定其 Z-Order。
  3. 输入事件处理:弹窗获得焦点时,WMS 将触摸事件路由到弹窗。

(3) 页面切换与窗口生命周期

  • Activity 切换:旧 Activity 的窗口被标记为 DESTROYED,新窗口添加到堆栈顶部。
  • 过渡动画:WMS 协调新旧窗口的动画(如滑动、淡入淡出),确保平滑切换。

4. WindowManagerService 的核心机制

(1) 窗口的添加与移除

  • 添加窗口
    • 应用调用 WindowManager.addView()
    • WMS 通过 Binder IPC 接收请求,分配窗口标识符(WindowId)和 Surface
  • 移除窗口
    • 应用调用 WindowManager.removeView()
    • WMS 销毁窗口并释放资源(如 Surface)。

(2) 布局计算(Layout)

  • 窗口尺寸:根据 LayoutParams(如 MATCH_PARENTWRAP_CONTENT)和父窗口约束计算。
  • 位置调整
    • 重力(Gravity):控制窗口在屏幕中的对齐方式。
    • 偏移量(x/y):手动指定窗口位置(如 Toast 的底部显示)。

(3) 输入事件路由

  • 触摸事件分发
    • WMS 根据窗口层级和位置,确定哪个窗口应接收事件。
    • 通过 InputDispatcher 将事件发送到目标窗口的应用进程。
  • 焦点管理
    • 窗口获得焦点时,WMS 通知应用进程(触发 onWindowFocusChanged())。

(4) 合成与显示

  • Surface 提交:每个窗口的渲染结果写入 Surface 的 Back Buffer。
  • SurfaceFlinger 合成:按窗口层级(Z-Order)混合所有 Surface,输出到屏幕。

5. 典型场景分析

(1) 弹窗覆盖输入法

  • 问题:输入法窗口(系统窗口,层级 2000+)应覆盖应用窗口,但弹窗可能遮挡输入法。
  • 解决:输入法窗口的层级高于普通应用弹窗,WMS 确保输入法始终位于最前。

(2) 多应用分屏

  • 流程
    1. 用户进入分屏模式,WMS 为两个应用分配独立区域。
    2. 每个应用的窗口尺寸被限制为分屏区域大小。
    3. 输入事件根据触摸位置路由到对应应用。

(3) 系统警报窗口(如来电提醒)

  • 优先级:系统警报窗口(层级 3000+)覆盖所有其他窗口。
  • 焦点抢夺:即使其他窗口正在交互,警报窗口也会立即获得焦点。

6. 关键优化与调试

(1) 性能优化

  • 减少窗口层级:避免不必要的窗口叠加(如多个透明 Dialog)。
  • 硬件加速:启用 GPU 渲染,减少主线程负担。
  • 避免泄漏:及时移除不再使用的窗口(如 PopupWindow.dismiss())。

(2) 调试工具

  • dumpsys window:查看所有窗口的层级、尺寸和状态。
    adb shell dumpsys window
    
  • Layout Inspector:分析应用内窗口的视图层级。
  • Systrace:监控窗口布局和绘制的耗时。

总结

WindowManagerService 作为 Android 窗口管理的核心,通过以下机制协调多应用、多窗口的复杂性:

  1. 层级控制(Z-Order):按窗口类型和优先级决定显示顺序。
  2. 布局计算:动态调整窗口尺寸和位置。
  3. 输入路由:确保焦点窗口正确接收用户交互。
  4. 生命周期管理:处理窗口的创建、销毁和切换。

理解这些机制,开发者可以更好地处理弹窗、多任务等场景,同时规避性能问题和显示异常。


在 Android 系统中,窗口管理涉及 多进程协作,核心对象(如 View 树、窗口树、Layer 树)分布在不同的进程中,通过跨进程通信(IPC)和共享内存机制交互。以下是各对象的创建者、所属进程和跨进程操作方式的详细解析:


1. 对象归属与创建者

(1) View 树

  • 创建者:应用进程(主线程)。
  • 所属进程:应用进程(如 com.example.app)。
  • 组成
    • 根视图DecorView(由 PhoneWindow 创建)。
    • 子 View:通过 LayoutInflater 解析 XML 或代码动态添加的 ViewViewGroup

(2) 窗口树(WindowState 树)

  • 创建者WindowManagerService(WMS)。
  • 所属进程system_server 进程(系统服务进程)。
  • 组成
    • 窗口节点WindowState(每个窗口对应一个 WindowState,存储窗口的尺寸、层级、Surface 等信息)。
    • 管理逻辑:WMS 维护全局窗口树,按 Z-Order 排序。

(3) Layer 树

  • 创建者SurfaceFlinger
  • 所属进程surfaceflinger 进程(负责合成的系统服务进程)。
  • 组成
    • 图层节点Layer(每个窗口对应一个 Layer,存储图层的 GraphicBuffer、变换矩阵等)。
    • 合成逻辑SurfaceFlinger 按 Z-Order 合成所有 Layer

2. 跨进程操作方式

(1) 应用进程 ↔ WindowManagerService

  • 通信方式:Binder IPC。

  • 关键操作

    • 添加/移除窗口
      • 应用调用 WindowManager.addView(),通过 Binder 调用 WMS.addWindow()
      • WMS 创建 WindowState 并分配 Surface
    • 更新窗口属性
      • 应用调用 WindowManager.updateViewLayout(),通知 WMS 调整窗口尺寸、层级等。
    • 输入事件路由
      • WMS 通过 InputDispatcher 将触摸事件发送到应用进程的 ViewRootImpl
  • 数据传递

    • 窗口参数WindowManager.LayoutParams 通过 Binder 传递。
    • Surface 控制:WMS 通过 SurfaceControl(Binder 对象)授予应用进程访问 Surface 的权限。

(2) 应用进程 ↔ SurfaceFlinger

  • 通信方式:共享内存 + Binder IPC。
  • 关键操作
    • 提交渲染数据
      • 应用通过 eglSwapBuffers() 将渲染结果写入 SurfaceGraphicBuffer(共享内存)。
      • 通过 IGraphicBufferProducer.queueBuffer()(Binder 调用)通知 SurfaceFlinger 有新帧。
    • 缓冲区管理
      • BufferQueue(应用与 SurfaceFlinger 共享的双缓冲队列)通过 Gralloc 驱动分配共享内存。

(3) WMS ↔ SurfaceFlinger

  • 通信方式:Binder IPC。
  • 关键操作
    • 窗口层级同步
      • WMS 通知 SurfaceFlinger 窗口的 Z-Order 和可见性。
    • 合成策略调整
      • 根据窗口属性(如透明、动画)选择 GPU 合成或硬件合成器(HWComposer)。

3. 关键对象生命周期

(1) View 树生命周期

  • 创建:由应用进程的 ActivityFragment 触发,通过 setContentView() 解析 XML。
  • 销毁Activity.onDestroy() 时,ViewRootImpl 调用 WindowManager.removeView() 移除窗口,触发 WMS 销毁 WindowState

(2) WindowState 生命周期

  • 创建WMS.addWindow() 时生成。
  • 销毁:应用调用 removeView() 或窗口关闭时,WMS 移除 WindowState 并释放 Surface

(3) Layer 生命周期

  • 创建:首次提交 GraphicBuffer 时,SurfaceFlinger 为窗口创建 Layer
  • 销毁:窗口移除或 Surface 释放时,SurfaceFlinger 销毁 Layer

4. 跨进程数据流示例(以弹窗显示为例)

  1. 应用进程
    • 创建 PopupWindow,调用 WindowManager.addView()
  2. WMS
    • system_server 进程创建 WindowState,分配 Surface
  3. 应用进程
    • 通过 SurfaceCanvas 或硬件加速渲染弹窗内容。
  4. SurfaceFlinger
    • 接收 GraphicBuffer,创建 Layer 并按 WMS 指定的 Z-Order 合成。
  5. 显示硬件
    • 在下一个 VSync 周期显示合成后的帧。

5. 技术总结

  • 进程边界
    • 应用进程:管理 View 树和本地窗口渲染。
    • system_server:WMS 管理全局窗口树。
    • surfaceflinger:SurfaceFlinger 管理 Layer 树和合成。
  • 跨进程机制
    • Binder IPC:用于控制信令(如窗口添加、属性更新)。
    • 共享内存:通过 GraphicBuffer 传递像素数据(避免拷贝开销)。
  • 性能关键点
    • 减少不必要的窗口层级和透明区域(降低合成负载)。
    • 避免频繁的跨进程调用(如多次 addView/removeView)。

通过这种多进程协作机制,Android 实现了复杂的窗口管理功能,同时保证了性能和安全性。开发者应理解这些底层交互,以优化 UI 渲染和避免跨进程瓶颈。


在 Android 系统中,视图渲染数据窗口管理信息最终渲染数据的转化与协作,是一个跨进程、分层级的高效流程。以下是它们的关联与转化过程:


1. 视图渲染数据(应用进程内生成)

(1) 数据内容

  • View 树的绘制指令:通过 View.draw() 生成的图形操作(如绘制矩形、文本、图片)。
  • 硬件加速优化
    • DisplayList:记录绘制命令的指令集(如 Canvas.drawRect() 转换为 GPU 指令)。
    • RenderNode:硬件加速的绘制单元,支持属性动画和变换。

(2) 生成流程

  1. Measure/Layout:确定每个 View 的尺寸和位置。
  2. Draw
    • 软件绘制:直接在 Canvas 上操作 Bitmap(CPU 生成像素数据)。
    • 硬件加速:将 Canvas 操作转换为 DisplayList,由 RenderThread 提交到 GPU 渲染。

(3) 数据形式

  • 软件绘制Bitmap 像素数据。
  • 硬件加速DisplayListRenderNode(GPU 指令的抽象)。

2. 窗口管理信息(系统进程管理)

(1) 数据内容

  • 窗口属性:尺寸、位置、层级(Z-Order)、可见性、焦点状态。
  • 窗口树结构:由 WindowManagerService(WMS)维护的全局窗口列表(WindowState 列表)。

(2) 管理流程

  1. 窗口创建:应用调用 WindowManager.addView(),WMS 分配 Surface 并创建 WindowState
  2. 层级排序:根据窗口类型(应用窗口、系统窗口)和添加顺序计算 Z-Order。
  3. 输入事件路由:根据窗口层级和触摸位置确定目标窗口。

(3) 数据形式

  • WindowState:系统进程(system_server)中的对象,存储窗口属性。
  • SurfaceControl:控制 Surface 的创建和配置(如缓冲区大小、格式)。

3. 最终渲染数据(系统进程合成与硬件输出)

(1) 数据内容

  • 合成后的帧数据:所有窗口的渲染结果按 Z-Order 混合后的最终像素数据。
  • 硬件缓冲区GraphicBuffer(通过共享内存传递的像素缓冲区)。

(2) 合成流程

  1. 提交渲染数据:应用将渲染结果写入 Surface 的 Back Buffer(通过 eglSwapBuffers())。
  2. 图层收集SurfaceFlinger 从所有窗口的 BufferQueue 获取最新 GraphicBuffer
  3. 合成与输出:按 Z-Order 混合图层,写入显示硬件的 Front Buffer,由 VSync 信号触发屏幕刷新。

(3) 数据形式

  • GraphicBuffer:共享内存中的像素缓冲区(避免跨进程拷贝)。
  • 合成策略:使用 GPU 或硬件合成器(HWComposer)执行混合操作。

4. 三者如何发生关系?

(1) 视图渲染数据 → 窗口管理信息的绑定

  • Surface 的关联
    • 每个窗口对应一个 Surface,应用进程将视图渲染数据写入其 Back Buffer。
    • WMS 管理窗口的 Surface 属性(如尺寸、位置),决定它最终在屏幕上的显示区域。
  • 层级控制
    • WMS 维护窗口的 Z-Order,告诉 SurfaceFlinger 哪个窗口的图层应该覆盖在上层。

(2) 窗口管理信息 → 最终渲染数据的转化

  • 图层合成规则
    • SurfaceFlinger 根据 WMS 提供的窗口 Z-Order 和位置信息,决定图层的叠加顺序。
    • 透明区域和动画效果(如 Alpha 值)由 GPU 或 HWComposer 计算混合结果。
  • 跨进程数据传递
    • 应用进程通过 GraphicBuffer(共享内存)将渲染数据传递给 SurfaceFlinger
    • WMS 通过 Binder IPC 将窗口属性同步给 SurfaceFlinger

(3) 最终渲染数据 → 屏幕显示

  • 硬件协作
    • 显示控制器(Display Controller)从 Front Buffer 读取像素数据。
    • 通过屏幕的像素阵列和时序控制器(Timing Controller)输出光信号。

5. 全流程示例(以点击按钮触发 UI 更新为例)

  1. 应用进程

    • 用户点击按钮,修改 TextView 的文本,调用 invalidate()
    • ViewRootImpl 触发 performTraversals(),执行 Measure → Layout → Draw。
    • 生成新的 DisplayList(硬件加速)或 Bitmap(软件绘制)。
  2. 窗口管理(WMS)

    • WMS 维护窗口的尺寸和 Z-Order,确保该窗口位于其他窗口之上。
    • 如果窗口位置或层级变化,WMS 通过 Binder 通知 SurfaceFlinger
  3. 渲染数据提交

    • 渲染线程将 DisplayList 转换为 GPU 指令,写入 Surface 的 Back Buffer。
    • 通过 IGraphicBufferProducer.queueBuffer() 提交到 SurfaceFlinger
  4. 合成与显示

    • SurfaceFlinger 按 WMS 提供的 Z-Order 合成所有窗口的图层。
    • 合成后的帧通过 VSync 信号显示到屏幕。

6. 关键优化点

(1) 减少渲染数据量

  • 避免过度绘制:使用 canvas.clipRect() 限制绘制区域。
  • 硬件加速优化:复用 DisplayList,减少 GPU 指令生成开销。

(2) 降低窗口管理开销

  • 减少窗口层级:避免不必要的弹窗或透明窗口。
  • 批量更新属性:合并多次 View 属性修改,减少 IPC 调用。

(3) 合成效率提升

  • 使用不透明图层:避免 Alpha 混合计算。
  • 硬件合成器(HWComposer):利用专用硬件加速图层混合。

总结

  • 视图渲染数据是应用进程内生成的绘制指令或像素数据。
  • 窗口管理信息由 WMS 维护,决定窗口的显示属性和层级。
  • 最终渲染数据SurfaceFlinger 按窗口管理规则合成的结果。

三者通过 跨进程通信(Binder)共享内存(GraphicBuffer) 协作,最终由显示硬件输出到屏幕。理解这一流程,有助于开发者优化 UI 性能,避免卡顿和过度绘制。


在 Android 系统中,ActivityManagerService(AMS) 是负责管理应用组件(如 Activity、Service)生命周期、任务栈、进程调度和跨应用协作的核心系统服务。尽管 AMS 不直接参与窗口渲染或图层合成,但它通过与 WindowManagerService(WMS)SurfaceFlinger 及其他组件的协作,间接影响窗口的显示流程。以下是 AMS 在这些过程中的核心作用及协作机制:


1. 管理 Activity 生命周期,触发窗口的创建与销毁

(1) Activity 启动与窗口创建

  • 流程
    1. 应用调用 startActivity(),AMS 根据 Intent 解析目标 Activity。
    2. AMS 创建新 Activity 实例,并通知应用进程执行 onCreate()onStart()onResume()
    3. onResume() 阶段,应用通过 WindowManager.addView() 请求 WMS 添加窗口(如 DecorView)。
  • AMS 的角色
    • 管理 Activity 状态机,确保生命周期回调的正确执行。
    • 若目标 Activity 属于其他应用,AMS 会启动新进程并初始化组件。

(2) Activity 销毁与窗口移除

  • 流程
    1. 用户按返回键或调用 finish(),AMS 触发 onPause()onStop()onDestroy()
    2. onDestroy() 阶段,应用调用 WindowManager.removeView() 移除窗口。
  • AMS 的角色
    • 回收 Activity 资源,并通知 WMS 销毁关联的 WindowState

2. 维护任务栈(TaskStack),影响窗口的层级(Z-Order)

(1) 任务栈与窗口层级

  • 任务栈(Task):AMS 将同一应用的多个 Activity 组织成任务栈(后进先出)。
  • Z-Order 规则:WMS 根据 AMS 维护的任务栈顺序,决定窗口的显示层级。
    • 前台任务:窗口层级最高,覆盖其他任务。
    • 后台任务:窗口被暂停或隐藏(如 onStop()),层级降低。

(2) 多任务场景(分屏、画中画)

  • AMS 的协调
    • 分屏模式下,AMS 将两个任务标记为前台,WMS 为每个任务分配独立区域。
    • 画中画(PiP)模式下,AMS 通知 WMS 将视频窗口固定为系统窗口(高 Z-Order)。

3. 进程管理,保障窗口渲染的资源分配

(1) 进程生命周期与窗口渲染

  • 前台进程:拥有可见 Activity 的进程,AMS 优先分配 CPU/内存资源,确保窗口渲染流畅。
  • 后台进程:若进程被 AMS 标记为低优先级(如进入后台),可能被限制资源或终止,导致窗口无法更新。

(2) 进程死亡与恢复

  • 场景:应用进程因内存不足被 AMS 终止。
  • 恢复流程
    1. AMS 保存 Activity 状态(如 Bundle)。
    2. 用户返回应用时,AMS 重新启动进程并恢复 Activity。
    3. 应用重新创建窗口,触发完整绘制流程。

4. 协调转场动画与窗口切换

(1) Activity 切换动画

  • AMS 的协作
    • AMS 定义 Activity 转场动画类型(如 slide_in_right)。
    • WMS 根据动画类型,调整新旧窗口的变换矩阵(如平移、透明度),SurfaceFlinger 合成最终效果。

(2) 窗口焦点切换

  • 焦点传递
    1. AMS 通知 WMS 新 Activity 的窗口获得焦点。
    2. WMS 通过 InputDispatcher 将输入事件路由到新窗口。

5. 处理系统级弹窗与交互

(1) 权限请求对话框

  • 流程
    1. 应用请求敏感权限,AMS 拦截并弹出系统级对话框。
    2. 对话框作为高 Z-Order 系统窗口,由 WMS 管理。
  • AMS 的角色
    • 校验权限状态,控制对话框的显示逻辑。

(2) ANR 弹窗(Application Not Responding)

  • 流程
    1. AMS 检测到应用主线程阻塞(5 秒无响应)。
    2. AMS 创建 ANR 对话框(系统窗口),覆盖当前应用窗口。
    3. 用户可选择关闭应用或等待。

6. 跨进程通信与安全管控

(1) Binder IPC 的中介

  • 场景:应用 A 启动应用 B 的 Activity。
    1. 应用 A 通过 Binder 调用 AMS 的 startActivity()
    2. AMS 校验权限,启动应用 B 的进程。
    3. AMS 通知 WMS 为应用 B 分配窗口。

(2) 窗口权限校验

  • 系统窗口权限
    • 只有系统应用才能创建某些高 Z-Order 窗口(如状态栏)。
    • AMS 校验调用方权限,WMS 拒绝非法请求。

总结:AMS 与 WMS/SurfaceFlinger 的协作全貌

  1. AMS 驱动生命周期:决定何时创建/销毁 Activity,间接控制窗口的添加/移除。
  2. WMS 管理窗口属性:根据 AMS 维护的任务栈和焦点状态,设置窗口的 Z-Order、尺寸和位置。
  3. SurfaceFlinger 合成图层:按 WMS 提供的层级信息,混合所有窗口的渲染结果。
  4. AMS 保障进程存活:确保前台应用有足够资源维持窗口渲染。

性能优化视角

  • 减少 Activity 启动耗时:优化 onCreate() 和布局加载,避免 AMS 触发 ANR。
  • 避免内存泄漏:及时销毁不再使用的 Activity,防止 AMS 误判进程优先级。
  • 合理使用进程:多模块应用可拆分进程,AMS 会独立管理其窗口和资源。

在 Android 中,Activity、Window、DecorView、ViewRootImpl 和 View 之间的关系可以通过以下层次结构和协作流程来理解:


1. 组件定义与职责

组件职责
Activity管理用户界面和生命周期,作为应用与用户交互的入口。
Window抽象窗口概念,管理窗口的属性和内容(如背景、标题栏)。
DecorView窗口的根视图,包含系统装饰(状态栏、导航栏)和用户内容区域。
ViewRootImpl连接窗口与系统服务(如 WindowManagerService),管理视图的绘制和事件。
ViewUI 的基本单元,所有控件(如 TextView、Button)的基类。

2. 关系与协作流程

(1) Activity 创建 Window

  • 触发时机:在 Activity.attach() 方法中,创建 PhoneWindow(Window 的具体实现)。
  • 代码逻辑
    // Activity.java
    public void attach(...) {
        mWindow = new PhoneWindow(this);
        mWindow.setWindowManager(...);
    }
    

(2) Window 初始化 DecorView

  • 触发时机:当 Activity 第一次调用 setContentView() 时,PhoneWindow 创建 DecorView
  • 代码逻辑
    // PhoneWindow.java
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor(); // 创建 DecorView
        }
        mLayoutInflater.inflate(layoutResID, mContentParent);
    }
    
  • DecorView 结构
    • 标题栏(可选):由 android.R.id.title 标识。
    • 内容区域:由 android.R.id.content 标识,用户布局添加至此。

(3) ViewRootImpl 的创建与关联

  • 触发时机:在 ActivityThread.handleResumeActivity() 中,当 Activity 变为可见时。
  • 代码逻辑
    // ActivityThread.java
    public void handleResumeActivity(...) {
        ViewManager wm = activity.getWindowManager();
        wm.addView(decorView, params); // 触发 ViewRootImpl 创建
    }
    
  • ViewRootImpl 的作用
    • DecorView 添加到 WindowManager
    • 管理视图的测量(Measure)、布局(Layout)、绘制(Draw)。
    • 处理输入事件(触摸、按键)的分发。

(4) View 树的构建与绘制

  • 构建流程:通过 setContentView() 将用户布局添加到 DecorView 的内容区域,形成 View 树。
  • 绘制流程
    • 触发ViewRootImpl.performTraversals()
    • 步骤
      1. Measure:计算每个 View 的尺寸。
      2. Layout:确定每个 View 的位置。
      3. Draw:将 View 内容绘制到 Surface

3. 层次结构图示

+---------------------+
|      Activity        |  ← 管理生命周期和窗口
+---------------------+
          |
          | 持有
          ↓
+---------------------+
|       Window         |  ← 管理窗口属性和内容(PhoneWindow 实现)
+---------------------+
          |
          | 创建
          ↓
+---------------------+
|     DecorView        |  ← 根视图,包含系统装饰和用户内容
|---------------------|
| - TitleBar (可选)     |
| - Content (ID: content) | ← 用户布局添加至此(通过 setContentView())
+---------------------+
          |
          | 添加为窗口的根视图
          ↓
+---------------------+
|   ViewRootImpl       |  ← 管理绘制、事件分发和系统服务通信
+---------------------+
          |
          | 管理
          ↓
+---------------------+
|        View          |  ← UI 控件(TextView、Button 等)
+---------------------+

4. 关键交互场景

(1) 用户点击按钮

  1. 输入事件传递
    • ViewRootImpl 通过 InputEventReceiver 接收触摸事件。
    • 事件从 DecorView 开始,递归分发给子 View
  2. UI 更新
    • 修改 TextView 文本后,调用 invalidate() 触发重绘。
    • ViewRootImpl 调度 performTraversals(),执行绘制流程。

(2) Activity 切换

  1. 旧 Activity 销毁
    • onPause()onStop()onDestroy()
    • WindowManager 移除 DecorViewViewRootImpl 被销毁。
  2. 新 Activity 显示
    • DecorView 通过 ViewRootImpl 添加到 WindowManager
    • SurfaceFlinger 合成新窗口的图层。

5. 总结

  • Activity 是用户交互的容器,通过 Window 管理窗口。
  • Window 的具体实现是 PhoneWindow,负责初始化 DecorView 和用户内容。
  • DecorView 是窗口的根视图,包含系统装饰和用户布局。
  • ViewRootImpl 是连接应用与系统服务的桥梁,管理视图的绘制和事件。
  • View 是 UI 的构建单元,构成视图树并由 ViewRootImpl 驱动渲染。

这种分层架构使得 Android 能够高效管理复杂的 UI 和窗口交互,同时保证灵活性和性能。


在 Android 系统中,Activity、Window、DecorView、ViewRootImpl、View 均属于 应用进程,而系统服务(如 WindowManagerServiceSurfaceFlinger)运行在独立的 系统进程 中。以下是它们的进程归属和跨进程协作机制:


1. 进程归属

组件/服务所属进程说明
Activity应用进程(如 com.example.app用户交互的入口,管理 UI 生命周期。
Window应用进程抽象窗口,由 PhoneWindow 实现,管理 DecorView 和窗口属性。
DecorView应用进程窗口的根视图,包含系统装饰(状态栏)和用户布局(android.R.id.content)。
ViewRootImpl应用进程连接应用窗口与系统服务,管理视图的测量、布局、绘制和输入事件。
View应用进程UI 控件(如 TextViewButton)。
WMSsystem_server 系统进程管理窗口的创建、层级(Z-Order)、焦点和尺寸。
SurfaceFlingersurfaceflinger 系统进程合成所有窗口的图层(Layer),输出到屏幕。
AMSsystem_server 系统进程管理 Activity 生命周期、任务栈和进程调度。
IMSsystem_server 系统进程分发输入事件(触摸、按键)到目标窗口。

2. 进程间关联与协作

(1) 应用进程 ↔ 系统进程(WMS/AMS/IMS)

  • 通信机制Binder IPC
  • 典型场景
    • 窗口创建
      • 应用进程调用 WindowManager.addView(),通过 Binder 调用 WMS.addWindow()
      • WMS 在系统进程中创建 WindowState,分配 Surface,并通过 IWindowSession 返回结果。
    • 输入事件传递
      • IMS 在系统进程接收触摸事件,通过 InputDispatcher 发送到应用进程的 ViewRootImpl
      • ViewRootImpl 将事件分发给 DecorView 及其子 View
    • Activity 生命周期
      • AMS 通过 Binder 通知应用进程执行 onCreate()onResume() 等生命周期方法。

(2) 应用进程 ↔ SurfaceFlinger

  • 通信机制共享内存(GraphicBuffer) + Binder IPC
  • 典型场景
    • 渲染数据提交
      • 应用进程通过 GPU 渲染 UI 到 Surface 的 Back Buffer(共享内存)。
      • 通过 Binder 调用 IGraphicBufferProducer.queueBuffer() 通知 SurfaceFlinger 有新帧。
    • 图层合成
      • SurfaceFlingerBufferQueue 读取 GraphicBuffer,按窗口层级合成最终帧。
      • 合成结果通过显示控制器(Display Controller)输出到屏幕。

3. 跨进程协作流程示例

场景:用户启动 Activity

  1. AMS 启动进程
    • AMS 在系统进程中检查目标 Activity 的进程是否存在,若不存在则启动新进程。
  2. Activity 初始化
    • 应用进程创建 Activity 实例,调用 onCreate()setContentView() → 构建 DecorView
  3. 窗口注册到 WMS
    • ViewRootImpl 通过 WindowManager.addView()DecorView 添加到 WMS。
    • WMS 分配 Surface 并维护窗口的 WindowState
  4. 渲染与合成
    • 应用进程渲染 UI 到 Surface,提交到 SurfaceFlinger
    • SurfaceFlinger 合成所有窗口的图层,输出到屏幕。
  5. 输入事件处理
    • IMS 将触摸事件发送到应用进程的 ViewRootImpl,由 DecorView 分发到子 View

4. 关键对象与数据流

对象/数据所属进程跨进程传递方式说明
WindowStatesystem_serverBinder IPC(WindowManagerServiceWMS 内部管理的窗口状态,记录层级、尺寸等。
Surface应用进程共享内存(GraphicBuffer窗口的绘图缓冲区,通过 BufferQueue 共享。
InputChannel应用进程Binder IPC(InputDispatcher输入事件通道,由 IMS 创建并与应用进程绑定。
Layersurfaceflinger共享内存(GraphicBufferSurfaceFlinger 管理的图层数据。

5. 性能与安全机制

  1. 共享内存优化
    • GraphicBuffer 通过 Gralloc 驱动分配,应用进程和 SurfaceFlinger 直接访问,避免数据拷贝。
  2. Binder 线程池
    • 应用进程和系统服务通过 Binder 线程池处理并发请求,避免阻塞主线程。
  3. 权限控制
    • WMS 校验窗口类型权限(如系统窗口需 SYSTEM_ALERT_WINDOW 权限)。
    • AMS 校验跨应用启动 Activity 的权限。

总结

  • 应用进程:负责 UI 构建(Activity、View 树)、事件处理和本地渲染。
  • 系统进程:管理全局状态(窗口层级、输入事件、图层合成)。
  • 跨进程协作:通过 Binder IPC 传递控制信令,通过 共享内存 传递渲染数据,实现高效交互。
  • 核心流程:AMS 驱动生命周期 → WMS 管理窗口 → IMS 路由输入 → SurfaceFlinger 合成输出。

这一协作机制确保了 Android 在多进程环境下仍能提供流畅的 UI 体验和高效的资源管理。


在 Android 中,当应用进程通过 ViewRootImplWindowManager.addView()DecorView 添加到 WindowManagerService (WMS) 时,DecorView 本身不会直接跨进程传递。相反,系统通过以下方式完成跨进程通信和数据传递:


1. 跨进程传递的核心对象

DecorView 的信息是通过 窗口属性(WindowManager.LayoutParamsBinder 代理对象(IWindow 跨进程传递的,而非传递 DecorView 的实例。具体流程如下:

(1) 应用进程侧

  1. 创建 ViewRootImpl
    • WindowManagerGlobal.addView() 创建 ViewRootImpl,并关联 DecorView
  2. 封装窗口属性
    • 将窗口参数(尺寸、层级、类型等)封装到 WindowManager.LayoutParams
  3. 创建 Binder 代理对象
    • ViewRootImpl 创建一个 IWindow.Stub 的代理对象(W),用于与 WMS 通信。
    • 该代理对象实现了 IWindow 接口,允许 WMS 反向调用应用进程(如通知窗口焦点变化)。

(2) 跨进程调用

  • IPC 方法:通过 IWindowSession.addToDisplay() 向 WMS 发起跨进程调用。
  • 传递内容
    • IWindow 代理对象W):标识窗口的唯一性,用于 WMS 回调应用进程。
    • WindowManager.LayoutParams:窗口的元数据(如 typeflagswidthheight 等)。
    • 父窗口句柄(可选):若为子窗口(如弹窗),需指定父窗口的 IWindow 对象。

(3) WMS 系统进程侧

  1. 创建 WindowState
    • WMS 根据传递的 IWindowWindowManager.LayoutParams 创建 WindowState 对象。
    • WindowState 是 WMS 内部管理窗口的核心对象,存储窗口属性、层级(Z-Order)、Surface 等信息。
  2. 分配 Surface
    • WMS 通过 SurfaceControl 为窗口分配 Surface(绘图缓冲区),并通过 Binder 将 Surface 的控制权返回给应用进程。

2. 关键对象的作用

对象所属进程作用
DecorView应用进程窗口的根视图,管理用户界面布局。
ViewRootImpl应用进程连接 DecorView 和 WMS,驱动测量、布局、绘制,并处理输入事件。
IWindow.Stub应用进程Binder 服务端,接收 WMS 的回调(如焦点变化、窗口尺寸调整)。
IWindow 代理跨进程(Binder)WMS 通过该代理调用应用进程的方法(如 resized()dispatchAppVisibility())。
WindowState系统进程WMS 内部管理窗口状态的对象,存储窗口属性、Surface、层级等信息。

3. 数据传递示意图

应用进程(com.example.app)                         系统进程(system_server)
+-----------------------------+                     +-----------------------------+
|                             |                     |                             |
| 1. ViewRootImpl             |                     |                             |
|    - 关联 DecorView          |                     |                             |
|    - 创建 IWindow.Stub (W)   |                     |                             |
|                             |                     |                             |
| 2. WindowManagerGlobal      |                     |                             |
|    - 调用 addView()          |                     |                             |
|    - 封装 LayoutParams       |                     |                             |
|                             |                     |                             |
| 3. Binder IPC               |                     |                             |
|    - 调用 IWindowSession     |                     |                             |
|      .addToDisplay(W, params)|                     |                             |
|                             |                     |                             |
|                             |                     | 4. WMS                      |
|                             |                     |    - 创建 WindowState        |
|                             |                     |    - 分配 Surface           |
|                             |                     |    - 管理窗口层级            |
+-----------------------------+                     +-----------------------------+

4. 为什么不能直接传递 DecorView

  1. 进程隔离
    • Android 的进程隔离机制禁止直接传递对象(如 View)到其他进程。
    • DecorView 是应用进程内的复杂对象,包含大量与 UI 相关的状态和方法,无法直接序列化。
  2. 性能与安全
    • 直接传递视图层级会导致大量数据拷贝,影响性能。
    • 通过代理对象(IWindow)和元数据(LayoutParams)传递,保证安全性和效率。

5. 窗口内容(如 DecorView 的绘制)如何传递?

  • Surface 共享机制
    • WMS 为窗口分配 Surface(通过 SurfaceControl),应用进程通过 OpenGL 或 Canvas 将内容渲染到 Surface 的缓冲区。
    • Surface 的缓冲区通过 共享内存(GraphicBuffer 实现跨进程访问。
  • 合成与显示
    • SurfaceFlinger 从共享内存中读取所有窗口的渲染数据,按层级合成后输出到屏幕。

总结

  • 传递的内容
    • 窗口元数据WindowManager.LayoutParams(封装窗口属性)。
    • Binder 代理对象IWindow(用于双向通信)。
  • WMS 侧的对象WindowState(管理窗口状态)和 Surface(绘图缓冲区)。
  • DecorView 仍留在应用进程:它负责管理 UI 布局和绘制,最终内容通过共享的 Surface 传递到系统进程。

这种设计既保证了进程隔离的安全性,又通过共享内存和 Binder 代理实现了高效的窗口管理。


在 Android 系统中,Surface 是窗口内容绘制的核心对象,而 WindowState 是系统进程(system_server)中管理窗口状态的核心对象。当应用进程通过 WindowManager.addView() 添加窗口时,WindowManagerService (WMS) 在系统进程中创建 WindowState 并分配 Surface,随后将 Surface 的控制权通过跨进程机制传递给应用进程。以下是这一过程的详细机制:


1. Surface 的创建与跨进程传递

(1) 系统进程中的操作

  1. 创建 WindowState
    • 当应用调用 WindowManager.addView() 时,WMS 在系统进程中创建 WindowState,记录窗口的尺寸、层级(Z-Order)、输入通道等属性。
  2. 分配 Surface
    • WMS 通过 SurfaceControl(底层图形服务接口)为窗口分配 Surface
    • Surface 的底层是 图形缓冲区(GraphicBuffer,通过 Gralloc 驱动在共享内存(ashmem)中分配,允许多进程访问。
  3. 封装 Surface
    • Surface 对象本身无法直接跨进程传递,但 WMS 会返回其控制权的 代理对象(如 IGraphicBufferProducer)。
    • 代理对象通过 Binder IPC 传递,应用进程通过它操作 Surface

(2) 跨进程传递机制

  • Binder IPC
    • WMS 将 Surface 的控制权封装为 IWindowSession.addToDisplay() 的返回值。
    • 应用进程通过 SurfaceControlIGraphicBufferProducer 代理对象操作远程的 Surface
  • 共享内存
    • GraphicBuffer 通过 Gralloc 分配在共享内存中,应用进程和 SurfaceFlinger 均可访问,避免数据拷贝。

2. Surface 在应用进程中的形态

(1) 应用进程的 Surface 对象

  • 代理对象
    • 应用进程持有的 Surface 对象实际上是一个 Binder 代理对象(如 IGraphicBufferProducer),指向系统进程中的真实 Surface
    • 该代理对象通过 Parcel 序列化跨进程传递。
  • 图形缓冲区的操作
    • 应用进程通过代理对象获取 GraphicBuffer,将 UI 内容渲染到共享内存的缓冲区。
    • 示例:Canvas canvas = surface.lockCanvas(); 通过代理对象锁定缓冲区并获取 Canvas

(2) 关键类与接口

类/接口所属进程作用
Surface应用进程代理对象,封装对远程 GraphicBuffer 的操作(如锁定、提交缓冲区)。
IGraphicBufferProducer系统进程Binder 接口,定义缓冲区生产者的操作(如 dequeueBufferqueueBuffer)。
GraphicBuffer共享内存实际存储像素数据的缓冲区,跨进程共享。

3. WindowStateSurface 的对应关系

(1) 系统进程中的 WindowState

  • 职责
    • 存储窗口的元数据:尺寸、层级、焦点状态、输入通道等。
    • 管理 Surface 的生命周期(创建、销毁、尺寸调整)。
  • Surface 的关联
    • WindowState 持有 SurfaceControl,控制 Surface 的底层属性(如缓冲区大小、格式)。

(2) 应用进程中的 Surface 操作

  • 绘制流程
    1. 应用进程通过 Surface.lockCanvas() 获取 Canvas,执行 UI 绘制。
    2. 绘制完成后,调用 Surface.unlockCanvasAndPost(),通过代理对象通知 SurfaceFlinger 提交缓冲区。
  • 跨进程协作
    • SurfaceFlinger 监听 BufferQueue,当应用提交新帧时,按窗口层级(Z-Order)合成所有 Surface

4. 数据流示意图

应用进程                                系统进程(WMS)                        SurfaceFlinger
+-----------------------------+       +-----------------------------+       +-----------------------------+
|                             |       |                             |       |                             |
| 1. ViewRootImpl             |       |                             |       |                             |
|    - 调用 addView()          |       |                             |       |                             |
|                             |       |                             |       |                             |
| 2. 接收 Binder 返回的        |       | 3. WMS 创建 WindowState      |       |                             |
|    IGraphicBufferProducer   | ←---- |   和 SurfaceControl          |       |                             |
|                             |       |                             |       |                             |
| 4. 通过代理对象操作 Surface  |       |                             |       |                             |
|    - lockCanvas()           |       |                             |       |                             |
|    - 绘制到 GraphicBuffer    |       |                             |       |                             |
|    - unlockAndPost()        | ----- | ---------------------------- | -----> | 5. SurfaceFlinger 合成图层    |
|                             |       |                             |       |                             |
+-----------------------------+       +-----------------------------+       +-----------------------------+

5. 关键总结

  1. Surface 的跨进程本质
    • 应用进程持有的 Surface 是远程对象的代理,实际图形数据存储在共享内存的 GraphicBuffer 中。
    • 通过 Binder 代理(如 IGraphicBufferProducer)实现跨进程控制。
  2. WindowState 的作用
    • 系统进程中的 WindowState 管理窗口状态,与 Surface 的生命周期绑定。
  3. 性能与安全
    • 共享内存机制避免了像素数据的跨进程拷贝,提升渲染性能。
    • Binder 代理和权限控制(如 SYSTEM_ALERT_WINDOW)保障窗口操作的安全性。

通过这种机制,Android 实现了高效的多窗口管理和跨进程渲染协作,同时确保系统稳定性和安全性。


在 Android 系统中,ActivityWindow窗口管理器(WMS) 以及 Activity 栈(Task) 之间通过多层协作实现应用界面的显示与管理。以下是它们的关键关联和工作流程:


1. Activity 与 Window 的关联

(1) 创建 Window 对象

  • Activity 初始化时创建 Window

    • 每个 Activity 在 onCreate() 前会调用 attach() 方法,初始化一个 PhoneWindow 对象(Window 接口的实现类)。
    • PhoneWindow 是 Activity 的顶层窗口容器,管理 DecorView(窗口的根视图)。
    // Activity.java
    final void attach(...) {
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowManager(...);
    }
    

(2) 设置视图内容

  • setContentView()

    • Activity 调用 setContentView() 将布局文件解析为 View 树,并附加到 DecorViewcontentParent 区域。
    // Activity.java
    public void setContentView(int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }
    

(3) 窗口的显示

  • onResume() 时关联到 WindowManager

    • 当 Activity 进入前台(onResume()),系统通过 WindowManagerDecorView 添加到窗口层级中。
    • ViewRootImpl 作为窗口与 WMS 的桥梁,处理底层通信(如布局、绘制、输入事件)。
    // ActivityThread.java → handleResumeActivity()
    ViewManager wm = activity.getWindowManager();
    wm.addView(decorView, layoutParams); // 最终调用到 WindowManagerGlobal.addView()
    

2. Activity 栈与窗口的关系

(1) Activity 栈(Task)

  • 由 ActivityManagerService (AMS) 管理
    • Task 是 AMS 维护的 Activity 回退栈,决定 Activity 的启动顺序和返回逻辑。
    • 栈顶 Activity 的窗口位于屏幕最上层,其他 Activity 的窗口可能被隐藏或销毁。

(2) 窗口层级(Z-Order)

  • 由 WindowManagerService (WMS) 管理
    • WMS 维护所有窗口的 WindowState,根据 窗口类型(应用窗口、子窗口、系统窗口)层级值(Z-Order) 排序。
    • Activity 的窗口属于 应用窗口,其 Z-Order 由 AMS 的 Task 栈顺序决定。

(3) 协作流程

  • 切换 Activity
    1. AMS 将新 Activity 压入 Task 栈顶,通知 WMS 调整窗口层级。
    2. WMS 将新 Activity 的窗口设为前台窗口,旧 Activity 的窗口可能进入后台或被销毁。
    3. ViewRootImpl 通过 relayoutWindow() 更新窗口属性(如尺寸、可见性)。

3. 关键组件关系图

应用进程                                system_server(系统进程)
+-----------------------------+       +-----------------------------+       +-----------------------------+
| Activity                    |       | ActivityManagerService (AMS) |       | WindowManagerService (WMS)  |
| - PhoneWindow               |       | - 管理 Activity 栈 (Task)      |       | - 管理 WindowState 和 Z-Order |
| - DecorView (根视图)         |       | - 处理 Activity 生命周期       |       | - 处理窗口布局、合成、输入事件   |
| - ViewRootImpl              | ↔ Binder ↔ |                             | ↔ Binder ↔ |                             |
+-----------------------------+       +-----------------------------+       +-----------------------------+

流程说明

  1. Activity 启动
    • AMS 创建 Activity 实例,压入 Task 栈顶。
    • Activity 初始化 PhoneWindowDecorView,通过 ViewRootImpl 向 WMS 注册窗口。
  2. 窗口显示
    • WMS 根据 AMS 的 Task 栈顺序调整窗口 Z-Order。
    • ViewRootImpl 处理布局(measure/layout)和绘制(draw),通过 Surface 提交帧到 SurfaceFlinger
  3. Activity 切换
    • AMS 将旧 Activity 移至后台,新 Activity 压入栈顶。
    • WMS 更新窗口层级,旧窗口可能被隐藏(onStop())或销毁(onDestroy())。

4. 窗口管理器(WMS)的核心职责

  1. 窗口生命周期管理
    • 处理 addWindow()removeWindow()relayoutWindow() 请求。
    • 维护 WindowState,记录窗口属性(尺寸、可见性、输入通道等)。
  2. 层级与合成
    • 根据窗口类型(应用窗口、子窗口、系统弹窗)分配 Z-Order。
    • 将窗口的 Surface 按 Z-Order 排序,通知 SurfaceFlinger 合成最终图像。
  3. 输入事件分发
    • 通过 InputManagerService 将触摸事件路由到前台窗口。

5. Activity 栈与窗口的映射示例

假设应用有两个 Activity:MainActivityDetailActivity,启动顺序为 MainActivity → DetailActivity

Activity 栈(AMS)窗口状态(WMS)用户可见界面
Task: [Main, Detail]DetailActivity 的窗口 Z-Order 更高显示 DetailActivity
用户按下返回键 → MainActivity 回到栈顶WMS 将 MainActivity 的窗口提升到前台显示 MainActivity

6. 总结

  • Activity 是窗口的宿主
    • 每个 Activity 拥有一个 PhoneWindow,通过 DecorView 管理视图内容。
    • ViewRootImpl 连接应用进程与 WMS,处理窗口的底层操作。
  • AMS 与 WMS 分工协作
    • AMS 管理 Activity 栈,决定哪些 Activity 应该显示或隐藏。
    • WMS 管理窗口层级,确保前台 Activity 的窗口位于最上层。
  • 跨进程通信
    • AMS 和 WMS 通过 Binder IPC 与应用进程通信,协调 Activity 生命周期和窗口状态。

理解这些关联机制,有助于优化应用界面性能(如减少过度绘制)、处理窗口层级问题(如系统弹窗覆盖)以及调试窗口相关的异常(如黑屏、卡顿)。


在 Android 系统中,ActivityWindow窗口管理器(WMS) 以及 Activity 栈(Task) 之间通过多层协作实现应用界面的显示与管理。以下是它们的关键关联和工作流程:


1. Activity 与 Window 的关联

(1) 创建 Window 对象

  • Activity 初始化时创建 Window

    • 每个 Activity 在 onCreate() 前会调用 attach() 方法,初始化一个 PhoneWindow 对象(Window 接口的实现类)。
    • PhoneWindow 是 Activity 的顶层窗口容器,管理 DecorView(窗口的根视图)。
    // Activity.java
    final void attach(...) {
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowManager(...);
    }
    

(2) 设置视图内容

  • setContentView()

    • Activity 调用 setContentView() 将布局文件解析为 View 树,并附加到 DecorViewcontentParent 区域。
    // Activity.java
    public void setContentView(int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }
    

(3) 窗口的显示

  • onResume() 时关联到 WindowManager

    • 当 Activity 进入前台(onResume()),系统通过 WindowManagerDecorView 添加到窗口层级中。
    • ViewRootImpl 作为窗口与 WMS 的桥梁,处理底层通信(如布局、绘制、输入事件)。
    // ActivityThread.java → handleResumeActivity()
    ViewManager wm = activity.getWindowManager();
    wm.addView(decorView, layoutParams); // 最终调用到 WindowManagerGlobal.addView()
    

2. Activity 栈与窗口的关系

(1) Activity 栈(Task)

  • 由 ActivityManagerService (AMS) 管理
    • Task 是 AMS 维护的 Activity 回退栈,决定 Activity 的启动顺序和返回逻辑。
    • 栈顶 Activity 的窗口位于屏幕最上层,其他 Activity 的窗口可能被隐藏或销毁。

(2) 窗口层级(Z-Order)

  • 由 WindowManagerService (WMS) 管理
    • WMS 维护所有窗口的 WindowState,根据 窗口类型(应用窗口、子窗口、系统窗口)层级值(Z-Order) 排序。
    • Activity 的窗口属于 应用窗口,其 Z-Order 由 AMS 的 Task 栈顺序决定。

(3) 协作流程

  • 切换 Activity
    1. AMS 将新 Activity 压入 Task 栈顶,通知 WMS 调整窗口层级。
    2. WMS 将新 Activity 的窗口设为前台窗口,旧 Activity 的窗口可能进入后台或被销毁。
    3. ViewRootImpl 通过 relayoutWindow() 更新窗口属性(如尺寸、可见性)。

3. 关键组件关系图

应用进程                                system_server(系统进程)
+-----------------------------+       +-----------------------------+       +-----------------------------+
| Activity                    |       | ActivityManagerService (AMS) |       | WindowManagerService (WMS)  |
| - PhoneWindow               |       | - 管理 Activity 栈 (Task)      |       | - 管理 WindowState 和 Z-Order |
| - DecorView (根视图)         |       | - 处理 Activity 生命周期       |       | - 处理窗口布局、合成、输入事件   |
| - ViewRootImpl              | ↔ Binder ↔ |                             | ↔ Binder ↔ |                             |
+-----------------------------+       +-----------------------------+       +-----------------------------+

流程说明

  1. Activity 启动
    • AMS 创建 Activity 实例,压入 Task 栈顶。
    • Activity 初始化 PhoneWindowDecorView,通过 ViewRootImpl 向 WMS 注册窗口。
  2. 窗口显示
    • WMS 根据 AMS 的 Task 栈顺序调整窗口 Z-Order。
    • ViewRootImpl 处理布局(measure/layout)和绘制(draw),通过 Surface 提交帧到 SurfaceFlinger
  3. Activity 切换
    • AMS 将旧 Activity 移至后台,新 Activity 压入栈顶。
    • WMS 更新窗口层级,旧窗口可能被隐藏(onStop())或销毁(onDestroy())。

4. 窗口管理器(WMS)的核心职责

  1. 窗口生命周期管理
    • 处理 addWindow()removeWindow()relayoutWindow() 请求。
    • 维护 WindowState,记录窗口属性(尺寸、可见性、输入通道等)。
  2. 层级与合成
    • 根据窗口类型(应用窗口、子窗口、系统弹窗)分配 Z-Order。
    • 将窗口的 Surface 按 Z-Order 排序,通知 SurfaceFlinger 合成最终图像。
  3. 输入事件分发
    • 通过 InputManagerService 将触摸事件路由到前台窗口。

5. Activity 栈与窗口的映射示例

假设应用有两个 Activity:MainActivityDetailActivity,启动顺序为 MainActivity → DetailActivity

Activity 栈(AMS)窗口状态(WMS)用户可见界面
Task: [Main, Detail]DetailActivity 的窗口 Z-Order 更高显示 DetailActivity
用户按下返回键 → MainActivity 回到栈顶WMS 将 MainActivity 的窗口提升到前台显示 MainActivity

6. 总结

  • Activity 是窗口的宿主
    • 每个 Activity 拥有一个 PhoneWindow,通过 DecorView 管理视图内容。
    • ViewRootImpl 连接应用进程与 WMS,处理窗口的底层操作。
  • AMS 与 WMS 分工协作
    • AMS 管理 Activity 栈,决定哪些 Activity 应该显示或隐藏。
    • WMS 管理窗口层级,确保前台 Activity 的窗口位于最上层。
  • 跨进程通信
    • AMS 和 WMS 通过 Binder IPC 与应用进程通信,协调 Activity 生命周期和窗口状态。

理解这些关联机制,有助于优化应用界面性能(如减少过度绘制)、处理窗口层级问题(如系统弹窗覆盖)以及调试窗口相关的异常(如黑屏、卡顿)。


在 Android 系统中,窗口管理器服务(WindowManagerService, WMS) 负责管理所有窗口的层级(Z-Order)和显示状态。不同应用场景下,窗口栈(即窗口的 Z-Order 排列)会有不同的结构。以下是几种典型场景的窗口栈状态:


1. 没有应用运行时(仅系统窗口)

当设备处于空闲状态(无前台应用运行),窗口栈主要由系统窗口构成:

窗口栈(Z-Order 从高到低)
+-----------------------------+
| 1. 输入法窗口(如果需要)         | → 如键盘输入弹窗(TYPE_INPUT_METHOD)
+-----------------------------+
| 2. 系统弹窗(如电源菜单、通知栏)    | → TYPE_SYSTEM_DIALOG / TYPE_SYSTEM_ALERT
+-----------------------------+
| 3. 状态栏(Status Bar)         | → TYPE_STATUS_BAR
+-----------------------------+
| 4. 导航栏(Navigation Bar)     | → TYPE_NAVIGATION_BAR
+-----------------------------+
| 5. 壁纸(Wallpaper)           | → TYPE_WALLPAPER
+-----------------------------+
  • 特点:只有系统级窗口,无应用窗口。
  • WMS 行为:所有窗口层级由系统服务直接管理,应用窗口处于未激活状态。

2. 单个应用运行时(前台全屏 Activity)

当用户启动一个全屏应用(如主屏幕或单 Activity 应用):

窗口栈(Z-Order 从高到低)
+-----------------------------+
| 1. 应用的主窗口(Main Activity)  | → TYPE_BASE_APPLICATION(应用主窗口)
+-----------------------------+
| 2. 系统弹窗(如果需要)           | → 如 Toast(TYPE_TOAST)
+-----------------------------+
| 3. 状态栏 / 导航栏              | → 覆盖在应用窗口下方
+-----------------------------+
| 4. 壁纸                       | → 被应用窗口完全遮挡
+-----------------------------+
  • 特点
    • 应用的 TYPE_BASE_APPLICATION 窗口位于栈顶,覆盖系统窗口。
    • 状态栏和导航栏可能显示为沉浸式或透明(取决于应用配置)。
  • WMS 行为
    • 应用窗口通过 ViewRootImpl 注册到 WMS,获得最高优先级(前台窗口)。
    • 系统窗口(如状态栏)可能通过 FLAG_LAYOUT_IN_SCREENFLAG_LAYOUT_INSET_DECOR 与应用窗口共存。

3. 多个应用运行时(一个前台,一个后台)

当用户启动两个应用(如应用 A 在前台,应用 B 在后台):

窗口栈(Z-Order 从高到低)
+-----------------------------+
| 1. 应用 A 的主窗口(前台 Activity) | → TYPE_BASE_APPLICATION
+-----------------------------+
| 2. 应用 B 的主窗口(后台 Activity) | → 可能被标记为不可见或暂停(STATE_STOPPED)
+-----------------------------+
| 3. 系统弹窗(如通知栏)            | → TYPE_SYSTEM_ALERT
+-----------------------------+
| 4. 状态栏 / 导航栏               | → 覆盖在后台应用窗口上方
+-----------------------------+
  • 特点
    • 前台应用(A)的窗口位于栈顶,覆盖后台应用(B)的窗口。
    • 后台应用窗口可能被 WMS 标记为 不可见暂停,但仍保留在窗口栈中(取决于系统资源策略)。
  • WMS 行为
    • 当应用切换到后台时,WMS 通过 relayoutWindow() 更新其窗口状态(如隐藏 Surface)。
    • 窗口的 Surface 可能被销毁以节省资源,但 WindowState 对象仍保留(用于快速恢复)。

4. 多个应用同时前台运行(分屏或画中画)

当两个应用同时处于前台(如分屏模式或画中画):

窗口栈(Z-Order 从高到低)
+-----------------------------+
| 1. 画中画窗口(应用 B 的视频窗口)   | → TYPE_APPLICATION_OVERLAY(覆盖其他窗口)
+-----------------------------+
| 2. 分屏窗口(应用 A 的上半部分)    | → TYPE_BASE_APPLICATION(分屏任务 1+-----------------------------+
| 3. 分屏窗口(应用 C 的下半部分)    | → TYPE_BASE_APPLICATION(分屏任务 2+-----------------------------+
| 4. 系统弹窗(如输入法)           | → TYPE_INPUT_METHOD
+-----------------------------+
| 5. 状态栏 / 导航栏               | → 位于分屏窗口下方
+-----------------------------+
  • 特点
    • 分屏模式下,每个分屏区域的窗口属于不同的 Task,但都被视为前台窗口。
    • 画中画窗口(如视频播放器)作为 TYPE_APPLICATION_OVERLAY 类型,覆盖其他应用窗口。
  • WMS 行为
    • 分屏窗口的 Z-Order 由分屏位置决定(例如,上半部分窗口优先于下半部分)。
    • 画中画窗口通过 WindowManager.LayoutParams.flags 标记为可交互(FLAG_NOT_TOUCH_MODAL),允许穿透点击事件。

5. 多个应用弹窗覆盖(如系统级弹窗 + 应用弹窗)

当多个弹窗同时显示(如系统权限弹窗 + 应用对话框):

窗口栈(Z-Order 从高到低)
+-----------------------------+
| 1. 系统权限弹窗(如相机权限请求)    | → TYPE_SYSTEM_ALERT(最高优先级)
+-----------------------------+
| 2. 应用 A 的对话框              | → TYPE_APPLICATION(普通应用弹窗)
+-----------------------------+
| 3. 应用 B 的主窗口(后台)         | → TYPE_BASE_APPLICATION(暂停状态)
+-----------------------------+
| 4. 状态栏 / 导航栏               | → 覆盖在后台应用窗口上方
+-----------------------------+
  • 特点
    • 系统弹窗(TYPE_SYSTEM_ALERT)优先级高于普通应用弹窗(TYPE_APPLICATION)。
    • 系统弹窗会阻塞应用输入事件,直到用户响应。
  • WMS 行为
    • 系统弹窗通过 WindowManager.LayoutParams.type 标记为高优先级,强制置顶。
    • 应用弹窗的 Z-Order 由 typeflags 共同决定(例如 FLAG_LAYOUT_IN_SCREEN)。

关键规则总结

  1. 窗口类型决定基础层级
    • 系统窗口(如 TYPE_SYSTEM_ALERT) > 应用窗口(如 TYPE_BASE_APPLICATION) > 子窗口(如 TYPE_APPLICATION_PANEL)。
  2. 同一类型窗口按时间顺序排列
    • 后添加的窗口默认位于同一层级的上方(可通过 flags 调整优先级,如 FLAG_LAYER_TYPE)。
  3. 分屏和画中画的特殊处理
    • 分屏窗口共享前台状态,但 Z-Order 由分屏位置决定。
    • 画中画窗口作为 TYPE_APPLICATION_OVERLAY 类型,可覆盖其他应用窗口。
  4. 系统弹窗的强制置顶
    • 系统级弹窗(如权限请求)始终位于栈顶,阻塞用户操作。

调试工具

  • adb shell dumpsys window:查看当前窗口栈状态、WindowState 和 Z-Order。
  • adb shell dumpsys activity:查看 Activity 栈(Task)与窗口的映射关系。

通过理解这些场景,可以更好地优化应用窗口层级(如避免过度使用 SYSTEM_ALERT)、处理多窗口交互(如分屏适配),以及调试窗口覆盖问题(如弹窗被遮挡)。


在 Android 系统中,当多个应用运行且每个应用包含多个 Activity,同时考虑 Launcher 应用时,WindowManagerService(WMS) 通过以下机制管理窗口层级和窗口与进程的对应关系:


1. 窗口层级(Z-Order)管理

WMS 根据 窗口类型任务栈(Task)状态用户交互优先级 动态调整窗口的显示顺序。

(1) 窗口类型与默认优先级

窗口的层级由 WindowManager.LayoutParams.type 决定,优先级从高到低如下:

  1. 系统窗口:状态栏(TYPE_STATUS_BAR)、导航栏(TYPE_NAVIGATION_BAR)、系统弹窗(TYPE_SYSTEM_ALERT)。
  2. 应用窗口
    • 前台应用的主窗口(TYPE_BASE_APPLICATION)。
    • 子窗口(如对话框 TYPE_APPLICATION)。
  3. Launcher 窗口:属于普通应用窗口,但当用户返回桌面时,其窗口优先级提升。

(2) 任务栈与窗口层级

  • Activity 任务栈(Task)
    • ActivityManagerService(AMS) 维护,栈顶 Activity 的窗口会被 WMS 置顶。
    • 例如:用户从 Launcher 启动应用 A → 应用 A 启动应用 B → 应用 B 的窗口位于最上层。
  • 多 Activity 应用内部
    • 应用内不同 Activity 的窗口按任务栈顺序排列。例如,应用 A 的主 Activity 启动设置 Activity,设置窗口覆盖主窗口。

(3) Launcher 的特殊处理

  • Home 键触发:当用户按下 Home 键,AMS 将 Launcher 的 Activity 移至前台,WMS 将其窗口提升到层级顶部。
  • 后台保留:Launcher 的窗口可能被保留(不销毁)以加速下次启动,但层级被其他应用窗口覆盖。

2. 窗口与进程的对应关系

WMS 通过 进程标识(PID)窗口令牌(WindowToken) 跟踪窗口与进程的关系。

(1) 窗口的归属

  • 每个窗口绑定到进程:通过 ViewRootImpl 注册到 WMS 时,携带进程的 Binder 标识。
    // ViewRootImpl 向 WMS 添加窗口时,传递进程信息
    mWindowSession.addToDisplay(mWindow, mWindowAttributes, ...);
    
  • 窗口令牌(WindowToken):标识窗口所属的 Activity 或应用。例如:
    • Activity 窗口的 Token 由 AMS 分配。
    • 系统窗口的 Token 由 WMS 直接管理。

(2) 进程生命周期的影响

  • 进程终止:当应用进程崩溃或被杀死,WMS 移除该进程所有关联的窗口。
  • 后台进程窗口:后台应用的窗口可能被标记为不可见或销毁 Surface,但 WindowState 仍保留(用于快速恢复)。

3. 多应用运行时的典型场景

(1) 场景 1:Launcher 启动应用 A,应用 A 启动应用 B

  • 窗口层级
    1. 应用 B 的主窗口(栈顶 Activity)
    2. 应用 A 的主窗口(后台暂停)
    3. Launcher 窗口(完全隐藏)
    4. 系统状态栏/导航栏(始终覆盖应用窗口)
    
  • 进程关系
    • 应用 B 的进程在前台,应用 A 和 Launcher 的进程可能在后台存活。

(2) 场景 2:用户从应用 B 返回 Launcher

  • 窗口层级
    1. Launcher 窗口(恢复为前台)
    2. 应用 B 的主窗口(隐藏或销毁)
    3. 应用 A 的主窗口(保持后台)
    
  • 进程关系
    • Launcher 的进程恢复前台状态,应用 B 可能进入后台或终止(取决于内存策略)。

(3) 场景 3:分屏模式(Split-Screen)

  • 窗口层级
    1. 分屏上部分窗口(应用 C 的 Activity)
    2. 分屏下部分窗口(应用 D 的 Activity)
    3. 系统状态栏/导航栏
    
  • 进程关系
    • 应用 C 和 D 的进程同时处于前台,WMS 为每个分屏窗口分配独立 WindowState

4. WMS 的关键管理机制

(1) 窗口添加与移除

  • addWindow():根据窗口类型、令牌和进程信息创建 WindowState
  • removeWindow():当 Activity 销毁或进程终止时,清理关联窗口。

(2) 层级计算(WindowStack)

  • 动态调整 Z-Order:根据窗口类型、任务栈顺序和用户操作(如点击事件)实时排序。
  • 输入事件分发:仅前台窗口可接收触摸事件(通过 InputManagerService 路由)。

(3) 与 AMS 的协作

  • Activity 可见性通知:AMS 通知 WMS 哪些 Activity 应显示/隐藏。
  • 任务栈同步:WMS 根据 AMS 提供的任务栈信息调整窗口层级。

5. 调试与验证

  • 查看当前窗口层级
    adb shell dumpsys window
    
    输出示例:
    Window #0: Window{xxxx u0 com.android.launcher3/...}
    Window #1: Window{yyyy u0 com.example.appA/...}
    Window #2: Window{zzzz u0 StatusBar}
    
  • 查看进程与窗口关系
    adb shell dumpsys activity processes
    

6. 总结

  • 窗口层级由 WMS 动态管理:基于窗口类型、任务栈状态和用户交互。
  • 窗口与进程通过 Token 绑定:WMS 跟踪窗口的归属进程,确保进程终止时清理窗口。
  • Launcher 作为普通应用:其窗口优先级在用户返回桌面时提升,但遵循通用层级规则。
  • 多任务场景:分屏、画中画等模式需要特殊处理,但核心机制仍由 WMS 统一管理。

通过这一机制,Android 确保了多应用、多 Activity 环境下窗口的正确显示和交互逻辑。


在 Android 系统中,Activity 栈(Task)窗口层级(Window Stack) 是两个不同但密切相关的概念。Activity 栈由 ActivityManagerService (AMS) 管理,而窗口层级由 WindowManagerService (WMS) 控制。以下是它们的关系及具体运行机制:


1. Activity 栈与窗口的映射关系

(1) Activity 栈的结构

  • Task(任务栈):AMS 维护的 Activity 回退栈,每个 Task 中的 Activity 按启动顺序排列。
    • 栈顶 Activity:用户当前正在交互的 Activity。
    • 栈内其他 Activity:可能处于 PAUSEDSTOPPED 状态,窗口可能被隐藏或销毁。

(2) 每个 Activity 对应一个窗口

  • 窗口创建:每个 Activity 在 onCreate() 阶段创建 PhoneWindow,通过 setContentView() 加载视图。
  • 窗口注册:当 Activity 进入前台(onResume()),其窗口通过 WindowManager 注册到 WMS,成为可见窗口。

2. Activity 栈内的窗口管理

(1) 单应用场景(同一 Task 内多个 Activity)

假设应用内部启动流程:Activity A → Activity B → Activity C

  • AMS 的 Activity 栈
    Task Stack: [A, B, C](C 为栈顶)
    
  • WMS 的窗口层级
    Window Stack(Z-Order 从高到低):
    1. Activity C 的窗口(TYPE_BASE_APPLICATION,前台)
    2. Activity B 的窗口(可能被标记为隐藏或已销毁)
    3. Activity A 的窗口(可能被标记为隐藏或已销毁)
    4. 系统窗口(状态栏、导航栏等)
    
    • 关键行为
      • 只有 栈顶 Activity(C) 的窗口处于活跃状态(VISIBLE)。
      • 非栈顶 Activity(B, A)的窗口可能被:
        • 保留但隐藏:窗口的 Surface 被隐藏(setVisibility(GONE)),但 WindowState 仍存在。
        • 完全销毁:窗口从 WMS 移除(通常在内存紧张时发生)。

(2) 窗口的保留与销毁

  • 保留场景
    • 配置变更(如屏幕旋转):Activity 重建时,旧窗口可能暂存以便平滑过渡。
    • 快速返回:系统可能保留后台窗口的 Surface,以优化用户体验。
  • 销毁场景
    • 当 Activity 调用 finish() 或系统回收资源时,窗口从 WMS 移除。
    • 示例代码:Activity 销毁时调用 WindowManager.removeView(decorView)

3. 多应用场景(涉及 Launcher 和其他应用)

(1) 用户从 Launcher 启动应用

  • 初始状态
    • AMS 栈:Launcher 的 Activity 位于栈顶。
    • WMS 窗口层级:Launcher 的窗口在前台,覆盖其他系统窗口。
  • 启动应用后
    • AMS 栈:新应用的 Activity 压入栈顶,Launcher 进入后台。
    • WMS 窗口层级:新应用的窗口覆盖 Launcher 窗口,但 Launcher 窗口可能被保留(隐藏)。

(2) 用户返回桌面(按 Home 键)

  • AMS 行为:Launcher 的 Activity 重新压入栈顶,原应用进入后台。
  • WMS 行为
    • Launcher 的窗口被提升到前台(Z-Order 最高)。
    • 原应用的窗口被隐藏,但可能保留 WindowState(取决于系统策略)。

4. WMS 如何管理 Activity 栈内的窗口

(1) 关键机制

  1. 窗口令牌(WindowToken)
    • 每个 Activity 的窗口通过 IApplicationToken(由 AMS 分配)绑定到 WMS。
    • Token 用于标识窗口所属的 Activity 及其 Task。
  2. 窗口状态同步
    • AMS 通知 WMS Activity 的生命周期变化(如 onResume()onPause())。
    • WMS 根据这些事件调整窗口的可见性和层级。
  3. 输入事件路由
    • 仅栈顶 Activity 的窗口可以接收输入事件(触摸、按键)。

(2) 代码流程示例

  • Activity 切换时的窗口更新
    // AMS 通知 WMS 更新窗口
    // ActivityRecord.java
    void setVisible(boolean visible) {
        mWindowContainer.setVisible(visible);
        // 通过 WMS 更新窗口状态
    }
    
  • 窗口的隐藏与显示
    // WMS 处理窗口可见性
    // WindowManagerService.java
    void setWindowVisibility(IBinder token, boolean visible) {
        WindowState window = findWindowByToken(token);
        if (window != null) {
            window.setVisibility(visible ? VISIBLE : GONE);
        }
    }
    

5. 特殊场景分析

(1) 透明 Activity(如 Dialog Theme)

  • AMS 栈:透明 Activity(如 B)压入栈顶,原 Activity(A)仍可见。
  • WMS 窗口层级
    1. Activity B 的窗口(TYPE_APPLICATION,半透明)
    2. Activity A 的窗口(TYPE_BASE_APPLICATION,可见但不可交互)
    3. 系统窗口
    
    • 用户可与 B 交互,但 A 的窗口仍然渲染(如背景模糊效果)。

(2) 多窗口模式(分屏、自由窗口)

  • AMS 栈:每个分屏窗口对应独立 Task。
  • WMS 窗口层级
    1. 分屏窗口 1(Task A 的 Activity)
    2. 分屏窗口 2(Task B 的 Activity)
    3. 系统窗口
    
    • 每个分屏窗口的 Z-Order 根据其位置动态调整。

6. 总结

  • Activity 栈与窗口层级解耦
    • AMS 管理 Activity 的生命周期和任务逻辑。
    • WMS 管理窗口的渲染、层级和输入事件。
  • 窗口与 Activity 的绑定
    • 每个 Activity 对应一个窗口,但只有栈顶 Activity 的窗口处于活跃状态。
    • 非栈顶 Activity 的窗口可能被隐藏或销毁,具体行为由系统和资源策略决定。
  • 协作机制
    • AMS 和 WMS 通过 Binder IPC 同步 Activity 和窗口状态。
    • 用户看到的最终界面由 WMS 根据 AMS 的任务栈和窗口类型计算出的 Z-Order 决定。

通过这一机制,Android 实现了多 Activity、多应用场景下窗口的高效管理和用户体验的一致性。