握 Android 中 Window 与 WMS(WindowManagerService)完成绑定的全链路详细流程,包括从应用层触发绑定、跨进程通信到 WMS 内部处理的每一个核心环节 —— 这是理解 Window 如何从「内存对象」变为「屏幕可见界面」的核心,整个流程跨越应用进程和 SystemServer 进程,核心依赖 Binder 通信和 ViewRootImpl 的桥梁作用。下面我会以应用 Activity 的 Window(PhoneWindow) 为例,拆解从触发绑定到最终完成的完整步骤,并结合源码级逻辑说明关键细节。
一、核心前提:绑定流程的参与角色
先明确全流程的核心参与者,理解角色分工才能理清流程逻辑:
| 角色(进程) | 核心类 / 接口 | 作用 |
|---|---|---|
| 应用进程 | 1. WindowManagerImpl/WindowManagerGlobal(WindowManager 的实现)2. ViewRootImpl(应用 - WMS 桥梁)3. PhoneWindow(Window 具体实现)4. DecorView(Window 的顶级 View) | 触发绑定请求、创建通信桥梁、承载 UI 内容 |
| SystemServer 进程 | 1. WMS(WindowManagerService)2. IWindowSession(Binder 接口,WMS 的会话)3. WindowToken(Window 身份凭证)4. SurfaceControl(Surface 管理) | 接收绑定请求、校验 Window 合法性、分配 Surface、管理 Window 生命周期 |
| 通信桥梁 | IWindow/IWindowSession(AIDL 生成的 Binder 接口) | 应用进程与 WMS 的跨进程通信载体(ViewRootImpl 实现 IWindow,WMS 提供 IWindowSession) |
二、Window 与 WMS 绑定的完整流程(分 6 个核心阶段)
整个流程的核心入口是WindowManager.addView(),最终以 WMS 完成 Window 注册并分配 Surface 为绑定完成标志,流程可视化如下:
生成失败,请重试
阶段 1:前置准备 ——Window 与 WindowManager 初始化(应用进程)
这是绑定前的基础工作,Activity 启动时已完成:
- Activity.attach():创建
PhoneWindow实例(Activity 的专属 Window),并通过mWindow = new PhoneWindow(this)完成绑定; - PhoneWindow 初始化 WindowManager:PhoneWindow 通过
getWindowManager()返回WindowManagerImpl实例(WindowManager 的具体实现); - setContentView():给 PhoneWindow 的
DecorView加载开发者编写的布局,此时 DecorView 仅完成初始化,未与 WMS 绑定。
核心代码(简化):
java
运行
// Activity.java
final void attach(...) {
mWindow = new PhoneWindow(this); // 创建PhoneWindow
mWindowManager = mWindow.getWindowManager(); // 获取WindowManagerImpl
}
// PhoneWindow.java
public WindowManager getWindowManager() {
return mWindowManager != null ? mWindowManager : (mWindowManager = createLocalWindowManager());
}
private WindowManager createLocalWindowManager() {
return new WindowManagerImpl(mContext); // 初始化WindowManagerImpl
}
阶段 2:触发绑定 ——WindowManager.addView ()(应用进程)
Activity 执行onResume()后,系统会触发WindowManager.addView(),这是绑定流程的「启动开关」:
WindowManager是「门面类」,真正的逻辑在WindowManagerGlobal(全局单例,管理所有应用 Window)中;- 核心操作:将 DecorView、LayoutParams 传入,创建
ViewRootImpl(应用与 WMS 的核心桥梁)。
核心代码(简化):
java
运行
// WindowManagerImpl.java(门面类,转发请求)
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
// 转发给WindowManagerGlobal处理
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
// WindowManagerGlobal.java(核心处理类)
public void addView(View view, ViewGroup.LayoutParams params, ...) {
// 1. 参数校验:LayoutParams必须是WindowManager.LayoutParams
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
// 2. 关键:为当前Window创建ViewRootImpl(每个Window对应一个ViewRootImpl)
ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
// 3. 关联View、LayoutParams、ViewRootImpl
view.setLayoutParams(wparams);
mViews.add(view); // 存储所有Window的View
mRoots.add(root); // 存储所有ViewRootImpl
mParams.add(wparams); // 存储所有LayoutParams
try {
// 4. 调用ViewRootImpl.setView(),真正触发与WMS的绑定
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// 异常处理:移除已添加的View/ViewRootImpl
}
}
阶段 3:通信准备 ——ViewRootImpl.setView ()(应用进程)
ViewRootImpl.setView()是应用进程内的核心准备步骤,完成后将发起跨进程请求:
- 关联 DecorView:将 DecorView 赋值给 ViewRootImpl 的
mView成员,作为 Window 的顶级 Vi

最低0.47元/天 解锁文章
476

被折叠的 条评论
为什么被折叠?



