Android中的Window和WindowManager

Table of Contents

Android 中 Window 和 WindowManager 的关系及 View 的显示流程

一、Window 与 WindowManager 的关系

  1. Window 的概念

    • Window 是 Android 中窗口的抽象,代表一个可视化区域,每个 Activity、Dialog 等都对应一个 Window。
    • 核心实现是PhoneWindow,负责管理 View 层级(如 DecorView),包括标题栏、状态栏和内容区域。
  2. WindowManager 的作用

    • WindowManager(实现类为WindowManagerImpl)是系统服务,负责管理窗口的添加、更新和移除。
    • 通过WindowManagerGlobal与底层WindowManagerService(WMS)通信,处理窗口的层级、位置和动画等。
  3. 二者关系

    • Window 作为容器持有 View 树(如 DecorView),WindowManager 负责将 Window 中的 View 树添加到屏幕。
    • 每个 Window 通过 WindowManager 与系统交互,最终由 WMS 统一管理所有窗口的显示。

二、View 通过 WindowManager 显示的流程

  1. Activity 启动与 Window 创建

    • Activity 创建时,会初始化一个PhoneWindow,并通过setContentView()将布局添加到 DecorView 的内容区域(mContentParent)。
  2. 添加 View 到 WindowManager

    • ActivityThread.handleResumeActivity()阶段,系统调用WindowManager.addView(),将 DecorView 添加到窗口。
    • 此处创建ViewRootImpl,它是连接 View 树与 WMS 的核心类,负责处理测量、布局、绘制及输入事件。
  3. ViewRootImpl 的初始化与绘制

    • ViewRootImpl.setView()触发首次performTraversals(),执行以下步骤:
      • 测量(Measure):计算 View 树的大小(onMeasure())。
      • 布局(Layout):确定子 View 的位置(onLayout())。
      • 绘制(Draw):通过Surface将内容渲染到屏幕(onDraw())。
    • 绘制结果通过SurfaceFlinger合成,最终显示到屏幕上。
  4. 窗口管理参数

    • 通过WindowManager.LayoutParams设置窗口类型(如应用窗口、系统弹窗)、层级(Z-Order)和位置等属性,影响窗口显示优先级。

三、总结

  • Window 与 WindowManager:Window 是 View 的容器,WindowManager 是窗口的管理工具,二者协作实现 View 的显示。个人理解,Window 和 WindowManager 里的“Window”不是一个东西,Window 是系统上层为了配合 WindowManager 抽象出来的一个类,而 WindowManager 里的 Window 是一个概念,任何通过WindowManager.addView()方法添加进去的 View 都是这个概念 Window
  • View 显示流程:从 Activity 的setContentView()WindowManager.addView(),最终由ViewRootImpl驱动测量、布局、绘制,通过系统服务渲染到屏幕。
  • 关键角色DecorView作为根 View,ViewRootImpl负责与系统交互,WindowManagerService统一管理所有窗口。

示例代码(简化流程):

// Activity中初始化Window并设置ContentView
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // 将布局添加到Window的DecorView
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 系统内部调用WindowManager.addView()添加DecorView
    }
}

// 手动通过WindowManager添加View(如悬浮窗)
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
View floatingView = LayoutInflater.from(this).inflate(R.layout.floating_view, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    PixelFormat.TRANSLUCENT
);
windowManager.addView(floatingView, params); // 触发ViewRootImpl的绘制流程

通过以上机制,Android 实现了灵活的窗口管理和高效的 View 渲染。

明天了解一下 NextJs 的整体结构,最好能通过 Cursor 写一个简单的 demo 出来