解密:DecorView到底添加到哪里去了,为何能显示出来?

作为Android窗口系统的核心设计,WindowManager.addView() 添加 DecorView 的流程涉及 应用进程与系统服务(WMS)的跨进程协作 以及 图形显示系统的联动。以下是源码分析:


1. 添加的终点:WMS 管理的窗口层级

DecorView 最终被添加到 WindowManagerService (WMS) 维护的全局窗口列表 中,并通过 SurfaceFlinger 渲染到屏幕。关键步骤在 ViewRootImpl 中完成:

源码路径:

  • WindowManagerGlobal.addView()ViewRootImpl.setView()WindowSession.addToDisplay() (IPC) → WMS.addWindow()

2. 核心流程源码解析

(1) 应用进程:WindowManagerGlobal.addView()

java 复制代码
// WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params, ...) {
    ViewRootImpl root = new ViewRootImpl(context, display); // 创建ViewRootImpl
    root.setView(view, wparams, panelParentView); // 关键:关联DecorView
}

(2) ViewRootImpl.setView() :连接DecorView与WMS

java 复制代码
// ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    mView = view; // 持有DecorView实例
    requestLayout(); // 触发布局
    res = mWindowSession.addToDisplayAsUser(...); // IPC调用WMS!
}
  • mWindowSessionIWindowSession.Stub 的代理对象,通过 Binder IPC 与 WMS 通信。

(3) WMS 处理窗口添加:WMS.addWindow()

java 复制代码
// WindowManagerService.java
public int addWindow(Session session, IWindow client, ...) {
    WindowState win = new WindowState(...); // 创建窗口状态对象
    win.attach(); // 建立与客户端的连接
    mWindowMap.put(client.asBinder(), win); // 存入全局Map
    win.addWindowToListInOrderLocked(); // 根据Z-order排序
    WindowSurfaceController surfaceController = win.createSurfaceLocked(); // 创建Surface!
}
  • IWindow client :由 ViewRootImpl.W (Binder对象) 实现,用于 WMS 回调应用进程。
  • WindowState:WMS 中代表一个窗口的核心类,管理窗口状态、层级、动画等。

3. 显示的关键:Surface 的创建与绘制

(1) WindowState.createSurfaceLocked()

java 复制代码
// WindowState.java
void createSurfaceLocked() {
    mWinAnimator.createSurfaceLocked(); // 委托给WindowSurfaceController
}

// WindowSurfaceController.java
void createSurface() {
    mSurface = new Surface(); // 创建Surface对象
    Session.windowAddedLocked(...); // 通过SurfaceFlinger申请图形缓冲区
}
  • Surface :代表一个图形缓冲区,由 SurfaceFlinger 分配和管理。

(2) ViewRootImpl 触发绘制

java 复制代码
// ViewRootImpl.java
void performTraversals() {
    performMeasure();  // 测量
    performLayout();   // 布局
    performDraw();     // 绘制
}

private void performDraw() {
    draw(fullRedrawNeeded); // 触发硬件/软件绘制
}

private void draw(boolean fullRedrawNeeded) {
    Surface surface = mSurface; // 从WMS申请的Surface
    Canvas canvas = surface.lockCanvas(dirty); // 获取Canvas
    mView.draw(canvas); // DecorView绘制内容到Canvas
    surface.unlockCanvasAndPost(canvas); // 提交缓冲区到SurfaceFlinger!
}
  • unlockCanvasAndPost() :通过 BufferQueue 将图形缓冲区提交给 SurfaceFlinger 合成。

4. 显示到屏幕:SurfaceFlinger 合成

  1. 应用进程 :通过 Surface.unlockCanvasAndPost() 将帧数据放入 BufferQueue

  2. SurfaceFlinger

    • VSYNC 信号到达时,从所有窗口的 BufferQueue 中取帧。
    • 根据 WMS 提供的窗口层级(Z-order) 进行图层合成。
    • 将最终帧输出到 FrameBuffer 显示到屏幕。

关键设计总结

组件 作用
DecorView 窗口的根视图,承载UI内容,但自身不直接显示。
ViewRootImpl 连接 DecorView 与 WMS 的桥梁,负责测量、布局、绘制及IPC通信。
WMS 系统服务,管理所有窗口状态(WindowState)、层级和动画。
Surface 由 WMS 申请,SurfaceFlinger 分配的实际图形缓冲区,视图内容绘制于此。
SurfaceFlinger 系统服务,合成所有窗口的 Surface,输出到屏幕。

为何能显示?核心链条

  1. 窗口注册ViewRootImpl 通过 IPC 将 DecorView 添加到 WMS 的窗口树。
  2. Surface 分配:WMS 向 SurfaceFlinger 申请图形缓冲区(Surface)。
  3. 视图绘制ViewRootImplDecorView 内容绘制到 Surface。
  4. 缓冲区提交 :通过 unlockCanvasAndPost() 提交帧到 SurfaceFlinger。
  5. 图层合成:SurfaceFlinger 根据 WMS 提供的 Z-order 合成所有窗口的 Surface。
  6. 显示输出:合成后的帧通过 FrameBuffer 输出到物理屏幕。

关键点DecorView 本身只是一个普通 View 树,其显示能力完全依赖于 WMS 分配的 SurfaceViewRootImpl 的绘制提交机制。跨进程协作(应用 ↔ WMS ↔ SurfaceFlinger)是实现窗口显示的核心基础。

相关推荐
REDcker16 小时前
Android WebView 版本升级方案详解
android·音视频·实时音视频·webview·js·编解码
麦兜*16 小时前
【springboot】图文详解Spring Boot自动配置原理:为什么@SpringBootApplication是核心?
android·java·spring boot·spring·spring cloud·tomcat
le16161617 小时前
Android 依赖种类及区别:远程仓库依赖、打包依赖、模块依赖、本地仓库依赖
android
lxysbly17 小时前
psp模拟器安卓版带金手指
android
云上凯歌17 小时前
02 Spring Boot企业级配置详解
android·spring boot·后端
hqiangtai18 小时前
Android 高级专家技术能力图谱
android·职场和发展
aqi0018 小时前
FFmpeg开发笔记(九十七)国产的开源视频剪辑工具AndroidVideoEditor
android·ffmpeg·音视频·直播·流媒体
stevenzqzq18 小时前
Android Koin 注入入门教程
android·kotlin
炼金术18 小时前
SkyPlayer v1.1.0 - 在线视频播放功能更新
android·ffmpeg
用户2760381578118 小时前
鲲鹏+昇腾:开启 AI for Science 新范式——基于PINN的流体仿真加速实践
android