解密: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)是实现窗口显示的核心基础。

相关推荐
一碗情深17 分钟前
Android 开发环境解析:从SDK、NDK到版本兼容性指南
android·安卓·sdk·ndk
00后程序员张24 分钟前
App 上架全流程指南,iOS 应用发布步骤、ipa 文件上传工具、TestFlight 分发与 App Store 审核经验分享
android·ios·小程序·https·uni-app·iphone·webview
2501_9160137429 分钟前
iOS App 上架流程详解,苹果应用发布步骤、App Store 审核规则、ipa 文件上传与测试分发实战经验
android·ios·小程序·https·uni-app·iphone·webview
周杰伦的稻香2 小时前
MySQL中的空间碎片率计算分析
android·数据库·mysql
用户093 小时前
MVI架构如何改变Android开发模式
android·面试·kotlin
梦终剧4 小时前
【Android之路】.sp和界面层次结构
android
2501_916008894 小时前
iOS 26 软件性能测试全流程,启动渲染资源压力对比与优化策略
android·macos·ios·小程序·uni-app·cocoa·iphone
zh_xuan4 小时前
Android Handler源码阅读
android
雪饼android之路5 小时前
【Android】 android suspend/resume总结(3)
android·linux
00后程序员张5 小时前
iOS 26 兼容测试实战,机型兼容、SwiftUI 兼容性改动
android·ios·小程序·uni-app·swiftui·cocoa·iphone