Android中的Window和WindowManager
Table of Contents
Android 中 Window 和 WindowManager 的关系及 View 的显示流程
一、Window 与 WindowManager 的关系
-
Window 的概念
- Window 是 Android 中窗口的抽象,代表一个可视化区域,每个 Activity、Dialog 等都对应一个 Window。
- 核心实现是
PhoneWindow
,负责管理 View 层级(如 DecorView),包括标题栏、状态栏和内容区域。
-
WindowManager 的作用
- WindowManager(实现类为
WindowManagerImpl
)是系统服务,负责管理窗口的添加、更新和移除。 - 通过
WindowManagerGlobal
与底层WindowManagerService
(WMS)通信,处理窗口的层级、位置和动画等。
- WindowManager(实现类为
-
二者关系
- Window 作为容器持有 View 树(如 DecorView),WindowManager 负责将 Window 中的 View 树添加到屏幕。
- 每个 Window 通过 WindowManager 与系统交互,最终由 WMS 统一管理所有窗口的显示。
二、View 通过 WindowManager 显示的流程
-
Activity 启动与 Window 创建
- Activity 创建时,会初始化一个
PhoneWindow
,并通过setContentView()
将布局添加到 DecorView 的内容区域(mContentParent
)。
- Activity 创建时,会初始化一个
-
添加 View 到 WindowManager
- 在
ActivityThread.handleResumeActivity()
阶段,系统调用WindowManager.addView()
,将 DecorView 添加到窗口。 - 此处创建
ViewRootImpl
,它是连接 View 树与 WMS 的核心类,负责处理测量、布局、绘制及输入事件。
- 在
-
ViewRootImpl 的初始化与绘制
ViewRootImpl.setView()
触发首次performTraversals()
,执行以下步骤:- 测量(Measure):计算 View 树的大小(
onMeasure()
)。 - 布局(Layout):确定子 View 的位置(
onLayout()
)。 - 绘制(Draw):通过
Surface
将内容渲染到屏幕(onDraw()
)。
- 测量(Measure):计算 View 树的大小(
- 绘制结果通过
SurfaceFlinger
合成,最终显示到屏幕上。
-
窗口管理参数
- 通过
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 出来