目录
- 一、概述
- 二、核心概念
- 三、核心类详解
- [四、Window 添加流程](#四、Window 添加流程 "#%E5%9B%9Bwindow-%E6%B7%BB%E5%8A%A0%E6%B5%81%E7%A8%8B")
- [五、Surface 机制](#五、Surface 机制 "#%E4%BA%94surface-%E6%9C%BA%E5%88%B6")
- [六、SurfaceFlinger 详解](#六、SurfaceFlinger 详解 "#%E5%85%ADsurfaceflinger-%E8%AF%A6%E8%A7%A3")
- 七、输入事件处理
- 八、窗口动画系统
- 九、关键问题解答
一、概述
1.1 WMS 在 Android 系统中的定位
scss
┌─────────────────────────────────────────────────────────────────┐
│ Android 架构 │
├─────────────────────────────────────────────────────────────────┤
│ 应用层 (Application Layer) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Activity│ │ Service │ │ Receiver│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ └─────────────┴─────────────┘ │
│ │ │
│ ┌────────────────────▼────────────────────┐ │
│ │ WindowManager (Client) │ │
│ │ WindowManagerImpl/Global/ViewRootImpl│ │
│ └────────────────────┬────────────────────┘ │
│ │ Binder IPC │
│ ┌────────────────────▼────────────────────┐ │
│ │ WindowManagerService (Server) │ ← WMS │
│ │ ├─ 窗口管理 │ │
│ │ ├─ Surface 分配 │ │
│ │ ├─ 输入事件分发 │ │
│ │ └─ 动画系统 │ │
│ └────────────────────┬────────────────────┘ │
│ │ │
│ ┌────────────────────▼────────────────────┐ │
│ │ SurfaceFlinger (Native) │ │
│ │ └─ 图层合成/显示 │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
1.2 WMS 核心职责
| 职责 | 描述 |
|---|---|
| 窗口管理 | 管理所有窗口的创建、更新、删除、显示、隐藏 |
| 窗口层级 | 决定窗口的 Z-Order,处理窗口覆盖关系 |
| Surface 分配 | 为每个窗口分配 Surface,管理图形缓冲区 |
| 输入事件分发 | 接收输入事件并分发到对应的窗口 |
| 动画系统 | 处理窗口切换、启动、退出等动画效果 |
| 布局管理 | 计算窗口位置和大小,处理屏幕旋转等 |
| 多屏支持 | 管理多个显示屏的窗口显示 |
1.3 Window 是什么
Window 是一个抽象概念,表示一个"窗口"。
- Window 本身是一个抽象类:
android.view.Window - PhoneWindow 是其唯一实现:
com.android.internal.policy.PhoneWindow - Window 是视图的容器,所有 View 必须依附于 Window 存在
- Window 通过 WindowManager 进行管理
二、核心概念
2.1 Window 的类型
java
// frameworks/base/core/java/android/view/WindowManager.LayoutParams.java
/**
* 应用窗口类型 (Application Windows)
* 值范围:1-99
* 对应 Activity 窗口
*/
public static final int TYPE_BASE_APPLICATION = 1; // 基础应用窗口
public static final int TYPE_APPLICATION = 2; // 普通应用窗口
public static final int TYPE_APPLICATION_STARTING = 3; // 启动窗口
public static final int TYPE_DRAWN_APPLICATION = 4;
/**
* 子窗口类型 (Sub Windows)
* 值范围:1000-1999
* 必须依附于父窗口存在
*/
public static final int TYPE_APPLICATION_PANEL = 1000; // 面板窗口
public static final int TYPE_APPLICATION_MEDIA = 1001; // 媒体窗口
public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 子面板
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 对话框
/**
* 系统窗口类型 (System Windows)
* 值范围:2000-2999
* 需要 SYSTEM_ALERT_WINDOW 权限
*/
public static final int TYPE_STATUS_BAR = 2000; // 状态栏
public static final int TYPE_SEARCH_BAR = 2001; // 搜索栏
public static final int TYPE_PHONE = 2003; // 电话窗口
public static final int TYPE_SYSTEM_ALERT = 2003; // 系统警告
public static final int TYPE_TOAST = 2005; // Toast
public static final int TYPE_SYSTEM_OVERLAY = 2006; // 系统覆盖层
public static final int TYPE_INPUT_METHOD = 2011; // 输入法
public static final int TYPE_VOLUME_OVERLAY = 2016; // 音量覆盖层
2.2 Surface 与 Window 的关系
scss
┌─────────────────────────────────────────────────────────────┐
│ Window │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ PhoneWindow │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ DecorView │ │ │
│ │ │ ┌─────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │TitleBar │ │ ContentView│ │ StatusBar │ │ │ │
│ │ │ └─────────┘ └─────────────┘ └─────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ┌───────────────────────────────────────────┐ │ │ │
│ │ │ │ 用户布局 (XML) │ │ │ │
│ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │
│ │ │ │ │ Button │ │TextView │ │ │ │ │
│ │ │ │ └─────────┘ └─────────┘ │ │ │ │
│ │ │ └───────────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Surface (绘制目标) │ │
│ │ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ │ │
│ │ [Graphic Buffer - 图形缓冲区] │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
SurfaceFlinger
[图层合成]
2.3 SurfaceView vs TextureView vs View
| 类型 | Surface | 适用场景 | 特点 |
|---|---|---|---|
| 普通 View | 共享 Window 的 Surface | 一般 UI 控件 | 简单、省资源 |
| SurfaceView | 独立 Surface | 视频、相机、游戏 | 高性能、独立刷新、可能有黑边 |
| TextureView | 共享 Window 的 Surface (硬件加速) | 视频、相机预览、特效 | 灵活变换、性能稍差 |
| SurfaceControl | 控制 Surface 行为 | 系统级别控制 | 动画、层级管理等 |
三、核心类详解
3.1 核心类架构图
scss
应用层 (应用进程) 服务层 (System Server)
════════════════════════════════════════════════════════════════════════════════
┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ PhoneWindow │ │ WindowManager │ │ WMS │
│ │ │ Impl │ │ │
│ ├─ DecorView │ │ │ │ ├─ Session │
│ └─ Callback │ │ └─ mGlobal ─────┼─────────>│ ├─ WindowState │
└────────┬────────┘ └─────────────────┘ │ ├─ WindowToken │
│ │ ├─ DisplayContent
│ │ └─ Task
v └──────────────────┘
┌─────────────────┐ ┌─────────────────┐
│ WindowManager │ │ ViewRootImpl │
│ Global │<────────┤ │
│ │ │ ├─ mSurface │
│ ├─ mViews │ │ ├─ mSession │───────> (Binder IPC)
│ ├─ mRoots │ │ └─ mWindow │
│ └─ mParams │ └─────────────────┘
└─────────────────┘ │
│
┌──────────────┴──────────────┐
│ │
v v
┌─────────────────┐ ┌─────────────────┐
│ Choreographer│ │ IWindowSession │
│ (编舞者) │ │ (Binder接口) │
└─────────────────┘ └─────────────────┘
3.2 核心类职责表
| 类名 | 包路径 | 职责 | 所在层级 |
|---|---|---|---|
| PhoneWindow | com.android.internal.policy |
Window 唯一实现,管理 DecorView | 应用层 |
| DecorView | com.android.internal.policy |
窗口根视图,包含标题栏、内容区 | 应用层 |
| WindowManager | android.view |
接口,定义 addView/updateViewLayout/removeView | 应用层 |
| WindowManagerImpl | android.view |
WindowManager 实现,代理到 Global | 应用层 |
| WindowManagerGlobal | android.view |
单例,管理所有 View/RootImpl/Params | 应用层 |
| ViewRootImpl | android.view |
视图根实现,负责绘制、事件、IPC | 应用层 |
| Session | com.android.server.wm |
WMS 与客户端的会话连接 | 服务端 |
| WindowState | com.android.server.wm |
WMS 中窗口的状态表示 | 服务端 |
| WindowToken | com.android.server.wm |
窗口令牌,用于窗口分组 | 服务端 |
| DisplayContent | com.android.server.wm |
显示屏内容,管理一个显示设备 | 服务端 |
| Task | com.android.server.wm |
任务栈,管理 Activity 窗口 | 服务端 |
| AppWindowToken | com.android.server.wm |
应用窗口令牌,对应 Activity | 服务端 |
| WindowAnimator | com.android.server.wm |
窗口动画管理器 | 服务端 |
3.3 PhoneWindow 详解
java
// frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
public class PhoneWindow extends Window implements MenuBuilder.Callback {
// ========== 核心组件 ==========
/** 顶级视图容器 */
private DecorView mDecor;
/** 内容视图的父容器 (android.R.id.content) */
private ViewGroup mContentParent;
/** Activity 回调接口 */
private Callback mCallback;
/** 窗口特性 */
private int mFeatures;
/** 窗口特性本地风格 */
private int mLocalFeatures;
// ========== 核心方法 ==========
@Override
public void setContentView(int layoutResID) {
// 1. 如果 DecorView 不存在,则创建
if (mContentParent == null) {
installDecor();
}
// 2. 移除已存在的内容
if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
// 3. 加载布局到内容区域
mLayoutInflater.inflate(layoutResID, mContentParent);
// 4. 触发回调
mCallback.onContentChanged();
}
/**
* 安装 DecorView
*/
private void installDecor() {
if (mDecor == null) {
// 生成 DecorView
mDecor = generateDecor(-1);
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
}
if (mContentParent == null) {
// 根据窗口特性选择 DecorView 的布局
mContentParent = generateLayout(mDecor);
// 设置标题、图标等
setTitle(mTitle);
// ... 更多初始化
}
}
/**
* 生成 DecorView
*/
protected DecorView generateDecor(int featureId) {
return new DecorView(context, featureId, this, getAttributes());
}
/**
* 生成布局内容
* 根据不同的窗口特性选择不同的布局文件
*/
protected ViewGroup generateLayout(DecorView decor) {
// 获取窗口样式
TypedArray a = getWindowStyle();
// 根据特性选择布局资源
int layoutResource;
int features = getLocalFeatures();
// 系统选择不同的布局文件
if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
layoutResource = R.layout.screen_swipe_dismiss;
} else if ((features & (1 << FEATURE_LEFT_ICON)) != 0) {
layoutResource = R.layout.screen_left_icons;
}
// ... 更多布局选择
else {
// 默认布局
layoutResource = R.layout.screen_simple;
}
// 加载布局到 DecorView
mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
// 获取内容容器 (android.R.id.content)
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
return contentParent;
}
}
3.4 DecorView 详解
java
// frameworks/base/core/java/com/android/internal/policy/DecorView.java
public class DecorView extends FrameLayout implements RootViewSurfaceTaker {
// ========== 关键组件 ==========
/** PhoneWindow 的引用 */
PhoneWindow mWindow;
/** 窗口回调 */
private PhoneWindow.Callback mCallback;
/** 特性 ID */
private int mFeatures;
/** 窗口装饰视图容器 */
private View mDecorCaptionView;
// ========== 核心职责 ==========
/**
* 1. 作为窗口的根视图
* 2. 包含标题栏、内容区域等
* 3. 处理事件分发
* 4. 协调与 WMS 的交互
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// 回调给 Activity/Dialog
final Callback cb = getCallback();
return cb != null && !isDestroyed() && mFeatureId < 0
? cb.dispatchTouchEvent(ev)
: super.dispatchTouchEvent(ev);
}
@Override
public View onFocusSearch(View focused, int direction) {
// 焦点搜索
return super.onFocusSearch(focused, direction);
}
}
3.5 WindowManagerImpl 详解
java
// frameworks/base/core/java/android/view/WindowManagerImpl.java
public final class WindowManagerImpl implements WindowManager {
// 单例的 WindowManagerGlobal
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
// 父窗口 (用于子窗口)
private final Window mParentWindow;
// 显示屏
private final DisplayContext mContext;
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
@Override
public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.updateViewLayout(view, params);
}
@Override
public void removeView(View view) {
mGlobal.removeView(view, false);
}
@Override
public void removeViewImmediate(View view) {
mGlobal.removeView(view, true);
}
private void applyDefaultToken(@NonNull ViewGroup.LayoutParams params) {
// 如果没有 token,使用默认 token
if (mDefaultToken != null && mParentWindow == null) {
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
// 只有应用窗口才需要 token
if (((WindowManager.LayoutParams)params).type >= FIRST_APPLICATION_WINDOW
&& ((WindowManager.LayoutParams)params).type <= LAST_APPLICATION_WINDOW) {
((WindowManager.LayoutParams)params).token = mDefaultToken;
}
}
}
}
3.6 WindowManagerGlobal 详解
java
// frameworks/base/core/java/android/view/WindowManagerGlobal.java
public final class WindowManagerGlobal {
// ========== 存储所有 Window 相关信息的集合 ==========
/** 所有添加的 View (DecorView) */
private final ArrayList<View> mViews = new ArrayList<>();
/** 所有对应的 ViewRootImpl */
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<>();
/** 所有对应的 LayoutParams */
private final ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<>();
/** 正在被删除的 View */
private final Set<View> mDyingViews = new ArraySet<>();
// ========== 单例模式 ==========
private WindowManagerGlobal() {}
public static WindowManagerGlobal getInstance() {
synchronized (WindowManagerGlobal.class) {
if (sDefaultWindowManager == null) {
sDefaultWindowManager = new WindowManagerGlobal();
}
return sDefaultWindowManager;
}
}
// ========== 核心方法 ==========
/**
* 添加视图到 WindowManager
*/
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
// 1. 参数校验
if (view == null) {
throw new IllegalArgumentException("view must not be null");
}
if (display == null) {
throw new IllegalArgumentException("display must not be null");
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
// 2. 如果有父窗口,调整参数
if (parentWindow != null) {
parentWindow.adjustLayoutParamsForSubWindow(wparams);
}
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// 3. 检查是否已添加
int index = findViewLocked(view, false);
if (index >= 0) {
if (mDyingViews.contains(view)) {
// 正在被删除,等待删除完成
throw new IllegalStateException("View has been removed");
}
throw new IllegalStateException("View " + view + " has already been added");
}
// 4. 如果是子窗口,找到父窗口
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW
&& wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}
// 5. 创建 ViewRootImpl
root = new ViewRootImpl(view.getContext(), display);
// 6. 设置视图的 LayoutParams
view.setLayoutParams(wparams);
// 7. 添加到集合中
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
// 8. 设置视图到 ViewRootImpl
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// 异常处理,回滚
final int indexOfView = mViews.size() - 1;
if (indexOfView >= 0) {
mViews.remove(indexOfView);
mRoots.remove(indexOfView);
mParams.remove(indexOfView);
}
throw e;
}
}
}
/**
* 更新视图布局
*/
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
// ... 更新逻辑
}
/**
* 移除视图
*/
public void removeView(View view, boolean immediate) {
// ... 移除逻辑
}
}
3.7 ViewRootImpl 详解
java
// frameworks/base/core/java/android/view/ViewRootImpl.java
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.HardwareRendererCallbacks {
// ========== 核心组件 ==========
/** 与 WMS 通信的会话 */
final IWindowSession mWindowSession;
/** IWindow.Stub,WMS 回调客户端 */
final W mWindow;
/** 关联的视图 (DecorView) */
View mView;
/** 绘制表面 */
Surface mSurface;
/** 编排者,负责垂直同步 */
Choreographer mChoreographer;
/** 是否正在遍历 */
boolean mTraversalScheduled;
/** 遍历屏障 */
int mTraversalBarrier;
/** Surface 有效 */
boolean mSurfaceCreated = false;
/** 是否已完成首次布局 */
boolean mFirst;
/** 是否正在处理布局请求 */
boolean mHandlingLayoutInLayoutRequest;
// ========== 核心方法 ==========
/**
* 设置视图
* @param view 要添加的视图 (DecorView)
* @param attrs 窗口布局参数
* @param panelParentView 父面板视图
*/
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
// 1. 保存 LayoutParams
mWindowAttributes.copyFrom(attrs);
// 2. 关联视图和 ViewRootImpl
mView.assignParent(this);
// 3. 请求布局
requestLayout();
// 4. 处理输入事件
// ...
try {
// 5. 通过 IPC 调用 WMS 添加窗口
// 这是同步阻塞调用
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(
mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mWinFrame, mAttachInfo.mContentInsets,
mAttachInfo.mStableInsets, mAttachInfo.mOutsets,
mAttachInfo.mDisplayCutout, mInputChannel,
mInsetsState);
} catch (RemoteException e) {
// 异常处理
}
// 6. 处理结果
if (res < WindowManagerGlobal.ADD_OKAY) {
// 添加失败
mAddWindowFailed = true;
}
}
}
}
/**
* 请求布局
*/
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
/**
* 调度遍历
* 发送异步消息到消息队列
*/
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
// 发送同步屏障消息,拦截同步消息
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 发送遍历回调
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL,
mTraversalRunnable,
null);
}
}
/**
* 遍历执行的 Runnable
*/
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
/**
* 执行遍历
*/
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
// 移除同步屏障
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
if (mProfile) {
Debug.startMethodTracing("ViewRootImpl");
}
// 执行三大流程
performTraversals();
if (mProfile) {
Debug.stopMethodTracing();
mProfile = false;
}
}
}
/**
* 执行遍历 - 核心方法
*/
private void performTraversals() {
// ... 代码省略
// 1. 关联 Surface
relayoutWindow(params, viewVisibility, insetsPending);
// 2. 执行测量
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
// 3. 执行布局
performLayout(lp, mWidth, mHeight);
// 4. 执行绘制
performDraw();
}
/**
* 执行测量
*/
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
if (mView == null) {
return;
}
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
try {
// 测量所有子视图
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
/**
* 执行布局
*/
private void performLayout(WindowManager.LayoutParams lp,
int desiredWindowWidth, int desiredWindowHeight) {
// ... 布局逻辑
mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
}
/**
* 执行绘制
*/
private void performDraw() {
// ... 绘制逻辑
draw(fullRedrawNeeded);
}
/**
* 绘制
*/
private boolean draw(boolean fullRedrawNeeded) {
// 1. 创建或获取 Canvas
final Canvas canvas;
// 2. 硬件加速或软件绘制
if (mAttachInfo.mThreadedRenderer != null &&
mAttachInfo.mThreadedRenderer.isEnabled()) {
// 硬件加速绘制
mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
} else {
// 软件绘制
canvas = mSurface.lockCanvas(dirty);
mView.draw(canvas);
mSurface.unlockCanvasAndPost(canvas);
}
return true;
}
}
四、Window 添加流程
4.1 完整流程图
scss
┌──────────────────────────────────────────────────────────────────────────┐
│ Window 添加完整流程 │
└──────────────────────────────────────────────────────────────────────────┘
应用进程 System Server
════════════════════════════════════════════════════════════════════════════════
1. ActivityThread.handleLaunchActivity()
│
├─ Activity.performCreate()
│ └─ Activity.onCreate()
│ └─ PhoneWindow.setContentView(layoutResID)
│ ├─ installDecor() → 创建 DecorView
│ │ └─ generateDecor()
│ │ └─ generateLayout()
│ │ └─ 根据 features 选择布局文件
│ │ └─ 加载布局 (R.layout.screen_simple)
│ └─ mLayoutInflater.inflate(layoutResID, mContentParent)
│ └─ 解析 XML,创建 View 对象
│
├─ Activity.performResume()
│ └─ Activity.onResume()
│
└─ Activity.makeVisible()
└─ WindowManager.addView(DecorView, layoutParams)
└─ WindowManagerImpl.addView(view, params)
└─ WindowManagerGlobal.addView(view, params, display, parentWindow)
│
├─ 1. 参数校验和预处理
│ └─ applyDefaultToken()
│ └─ adjustLayoutParamsForSubWindow()
│
├─ 2. 创建 ViewRootImpl
│ └─ root = new ViewRootImpl(context, display)
│
├─ 3. 保存到集合
│ ├─ mViews.add(view)
│ ├─ mRoots.add(root)
│ └─ mParams.add(wparams)
│
└─ 4. ViewRootImpl.setView(DecorView, wparams, panelParentView)
│
├─ requestLayout() // 发送异步绘制消息
│ └─ scheduleTraversals()
│ └─ postSyncBarrier() // 发送同步屏障
│ └─ mChoreographer.postCallback() // 发送回调
│ └─ 加入 CallbackQueue
│
└─ mWindowSession.addToDisplay() ──────────────────────────> Binder IPC
│ │
│ │
│ V
│ Session.addToDisplay()
│ │
│ V
│ WMS.addWindow()
│ │
│ ├─ 1. 权限检查
│ │ └─ checkAddPermission()
│ │
│ ├─ 2. 获取 DisplayContent
│ │ └─ getDisplayContentOrCreate()
│ │
│ ├─ 3. 获取或创建 WindowToken
│ │ └─ getWindowToken()
│ │
│ ├─ 4. 创建 WindowState
│ │ └─ new WindowState(...)
│ │
│ ├─ 5. 建立父子关系
│ │ └─ win.mAttachedWindow = parentWindow
│ │
│ ├─ 6. 创建输入通道
│ │ └─ InputChannel.openInputChannelPair()
│ │
│ ├─ 7. 添加到窗口列表
│ │ └─ mWindowMap.put(client.asBinder(), win)
│ │
│ ├─ 8. 更新窗口层级
│ │ └─ assignWindowLayers()
│ │
│ ├─ 9. 创建 SurfaceControl
│ │ └─ win.createSurfaceLocked()
│ │
│ └─ 10. 返回 ADD_OKAY
│
│<─────────────────────────────────────────────────
│
V
addToDisplay 返回
│
V
[等待 TraversalRunnable 执行]
│
V
TraversalRunnable.run()
│
V
doTraversal()
│
V
performTraversals()
│
├─ performMeasure()
│ └─ mView.measure()
│ └─ DecorView.measure()
│ └─ 递归测量所有子 View
│
├─ performLayout()
│ └─ mView.layout()
│ └─ DecorView.layout()
│ └─ 递归布局所有子 View
│
└─ performDraw()
└─ draw()
└─ mView.draw(canvas)
└─ DecorView.draw()
└─ 递归绘制所有子 View
└─ 绘制到 Surface
4.2 关键时序说明
1. requestLayout 和 addToDisplay 的执行顺序
java
// ViewRootImpl.setView()
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
// 1. 先执行 requestLayout - 发送异步消息
requestLayout();
// ↓
scheduleTraversals();
// ↓
// 发送同步屏障 + 异步回调
// 此时绘制任务在消息队列中等待
// 不会立即执行
// 2. 再执行 addToDisplay - 同步阻塞调用
res = mWindowSession.addToDisplay(...);
// ↓
// Binder IPC 调用 WMS
// 阻塞等待 WMS 返回
// 必须等 WMS 完成窗口创建后才会继续
// 3. addToDisplay 返回后,继续执行
// 此时 WMS 已创建 WindowState
// 但 Surface 可能还未完全就绪
// 4. 当异步消息执行时 (performTraversals)
// 会再次调用 relayoutWindow 确保 Surface 已创建
}
}
}
2. 为什么能保证 Surface 已就绪
css
时序保证机制:
┌─────────────────────────────────────────────────────────────────────────┐
│ │
│ T1: setView() 调用 │
│ │ │
│ ├─ requestLayout() ──────────────────┐ │
│ │ │ │
│ │ [发送异步消息到 Handler 消息队列] │ │
│ │ │ │
│ ├─ addToDisplay() ────────────────> │ [WMS 处理] │
│ │ │ │ │
│ │ ├─ 创建 WindowState │ │
│ │ ├─ 创建 InputChannel │ │
│ │ ├─ 返回 ADD_OKAY │ │
│ │ │ │ │
│ │ <──────────────────────────────────┘ │
│ │ │ │
│ │ T2: addToDisplay 返回 │
│ │ │ │
│ │ │ [Handler 继续处理消息队列中的消息] │
│ │ │ │
│ │ V │
│ │ performTraversals() 开始 │
│ │ │ │
│ │ ├─ relayoutWindow() ──────────────> [WMS] │
│ │ │ │ │
│ │ │ ├─ 确认 Surface 状态 │
│ │ │ ├─ 如未就绪,等待创建 │
│ │ │ └─ 返回 Surface 信息 │
│ │ │ │ │
│ │ <────────────────────────────────────┘ │
│ │ │ │
│ │ └─ 此时 Surface 已确保就绪,可以安全绘制 │
│ │ │
│ V │
│ 绘制到 Surface │
│ │
└─────────────────────────────────────────────────────────────────────────┘
关键点:
1. addToDisplay 是同步阻塞调用,必须等 WMS 完成
2. requestLayout 发送的是异步消息,在 addToDisplay 之后才执行
3. performTraversals 会再次调用 relayoutWindow 确保 Surface 就绪
4. performTraversals 内部有锁和状态检查,确保 Surface 就绪后才绘制
4.3 源码级别流程
java
// ========== 1. Activity 启动流程 ==========
// frameworks/base/core/java/android/app/ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 1. 创建 Activity
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
// 2. 恢复 Activity
handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished, true);
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 创建 Activity 实例
java.lang.ClassLoader cl = appContext.getClassLoader();
Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
// 调用 attach
activity.attach(appContext, getInstrumentation(), this, r.token, ...);
// 调用 onCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
return activity;
}
// frameworks/base/core/java/android/app/Activity.java
final void attach(Context context, ActivityThread aThread, ...) {
// 创建 PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
// 设置 WindowManager
mWindowManager = mWindow.getWindowManager();
}
@Override
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
// ========== 2. Activity 显示流程 ==========
// frameworks/base/core/java/android/app/ActivityThread.java
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, ...) {
// 1. 调用 onResume
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
// 2. 使窗口可见
Activity a = r.activity;
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l); // ← 关键:添加 DecorView
}
}
// 3. 让窗口可见
if (!r.activity.mFinished && willBeVisible) {
r.activity.makeVisible();
}
}
}
// frameworks/base/core/java/android/app/Activity.java
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
// ========== 3. WindowManager 添加流程 ==========
// frameworks/base/core/java/android/view/WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
// 如果有父窗口,调整参数
if (parentWindow != null) {
parentWindow.adjustLayoutParamsForSubWindow(wparams);
}
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// 创建 ViewRootImpl
root = new ViewRootImpl(view.getContext(), display);
// 设置 LayoutParams
view.setLayoutParams(wparams);
// 添加到集合
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
// 设置视图到 ViewRootImpl
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// 异常处理
}
}
}
// ========== 4. ViewRootImpl 设置视图 ==========
// frameworks/base/core/java/android/view/ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
mWindowAttributes.copyFrom(attrs);
mView.assignParent(this);
// 请求布局
requestLayout();
// 通过 IPC 调用 WMS
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(
mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mWinFrame, mAttachInfo.mContentInsets,
mAttachInfo.mStableInsets, mAttachInfo.mOutsets,
mAttachInfo.mDisplayCutout, mInputChannel,
mInsetsState);
} catch (RemoteException e) {
}
if (res < WindowManagerGlobal.ADD_OKAY) {
mAddWindowFailed = true;
}
}
}
}
// ========== 5. WMS 添加窗口 ==========
// frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outFrame, Rect outContentInsets, Rect outStableInsets,
Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout,
InputChannel outInputChannel) {
int[] appOp = new int[1];
int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay,
appOp, attrs.packageName);
if (res != WindowManagerGlobal.ADD_OKAY) {
return res;
}
synchronized (mGlobalLock) {
// 1. 获取 DisplayContent
DisplayContent displayContent = getDisplayContentOrCreate(displayId);
if (displayContent == null) {
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
// 2. 获取 WindowToken
WindowToken token = displayContent.getWindowToken(attrs.token);
// 3. 创建 WindowState
final WindowState win = new WindowState(this, session, client, token,
parentWindow, appOp[0], seq, attrs, viewVisibility,
session.mUid, session.mCanAddInternalSystemWindow);
// 4. 检查权限
if (win.mToken.token == null) {
}
// 5. 创建输入通道
if (attrs.type >= FIRST_APPLICATION_WINDOW) {
InputChannel[] inputChannels = InputChannel.openInputChannelPair(
win.toString());
win.setInputChannel(inputChannels[0]);
inputChannels[1].transferTo(outInputChannel);
mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
}
// 6. 添加到窗口列表
mWindowMap.put(client.asBinder(), win);
if (win.mAppToken != null) {
win.mAppToken.windows.add(win);
}
// 7. 更新窗口层级
displayContent.assignWindowLayers(false);
// 8. 创建 Surface (在 performTraversals 的 relayoutWindow 中真正创建)
win.mWinAnimator.createSurfaceLocked();
return WindowManagerGlobal.ADD_OKAY;
}
}
五、Surface 机制
5.1 Surface 是什么
Surface 是图形缓冲区的抽象容器,用于承载需要显示的图像数据。
scss
┌─────────────────────────────────────────────────────────────────┐
│ Surface 结构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Surface (Java) │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ mNativeObject (long) │ │ │
│ │ │ ↓ │ │ │
│ │ │ Native 层 Surface 指针 │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 功能: │ │
│ │ - lockCanvas(): 获取 Canvas 用于绘制 │ │
│ │ - unlockCanvasAndPost(): 提交绘制结果 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Graphic Buffer (图形缓冲区) │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ [像素数据:RGBA_8888 格式] │ │ │
│ │ │ Width × Height × 4 bytes │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
5.2 Surface 创建时机
scss
WindowState 创建 ──────────────────────────────────────────────────────── Surface 创建
时间轴:
T1 T2 T3
│ │ │
│ ViewRootImpl.setView() │ performTraversals() │ 绘制完成
│ │ │
│ ├─ requestLayout() │ ├─ relayoutWindow() │
│ │ └─ 异步消息 │ │ └─ WMS.relayoutWindow()│
│ │ │ │ └─ 创建 Surface │
│ └─ addToDisplay() │ └─ Surface 就绪 │
│ └─ 创建 WindowState │ │
│ │ │
V V V
5.3 Surface 创建详细流程
scss
应用进程 System Server Native
════════════════════════════════════════════════════════════════════════════════
ViewRootImpl.performTraversals()
│
├─ performMeasure() // 测量
├─ performLayout() // 布局
│
└─ relayoutWindow() ─────────────────────────────────────────────────────────────────────────>
│ │
│ mWindowSession.relayout() │
│ │
V │
Session.relayout() │
│ │
└───────────────────────────────────────────────────────────────────────────────────────────>
WMS.relayoutWindow() │
│ │
├─ WindowStateAnimator.createSurfaceLocked() │
│ │ │
│ ├─ SurfaceControl.init() │
│ │ │ │
│ │ └─ new SurfaceControl(...) │
│ │ │ │
│ │ └─ nativeCreate() ────────────────────────────────────────────────────>
│ │ │
│ │ Native:
│ │ │
│ │ SurfaceComposerClient
│ │ │
│ │ createSurface()
│ │ │
│ │ │
│ │ ┌─────────────────────┐
│ │ │ SurfaceFlinger │
│ │ │ └─ createLayer() │
│ │ │ └─ 返回 Layer handle│
│ │ └─────────────────────┘
│ │ │
│ │<───────────────────────────────────────────────────────────────────────────────
│ │
│ └─ Surface 创建完成
│
├─ 返回 Surface 信息到客户端
│
└───────────────────────────────────────────────────────────────────────────────────────────
│ │
V │
mSurface.copyFrom(surface) │
│ │
V │
Surface 创建完成 │
│ │
V │
performDraw() │
│ │
└─ mSurface.lockCanvas() ──────────────────────────────────────────────────────────────────>
│ │
V │
draw(canvas) │
│ │
└─ 绘制到 Canvas │
│ │
V │
mSurface.unlockCanvasAndPost() ───────────────────────────────────────────────────────────────>
│ │
V │
queueBuffer() ─────────────────────────────────────────────────────────────────────────────────>
│ │
V │
Graphic Buffer 提交给 SurfaceFlinger │
│ │
V │
SurfaceFlinger 合成并显示 │
5.4 Surface 相关类详解
java
// frameworks/base/core/java/android/view/Surface.java
public class Surface implements Parcelable {
// Native 层 Surface 指针
private long mNativeObject;
// 构造函数
public Surface() {
}
/**
* 从 SurfaceControl 复制 Surface
*/
public void copyFrom(SurfaceControl other) {
if (other == null) {
throw new IllegalArgumentException("other must not be null");
}
long nativeHandle = other.mNativeObject;
if (nativeHandle == 0) {
throw new NullPointerException("SurfaceControl has no native object");
}
// Native 方法调用
mNativeObject = nativeCreateFromSurfaceControl(nativeHandle);
}
/**
* 锁定 Canvas,用于绘制
*/
public Canvas lockCanvas(Rect inOutDirty) {
synchronized (mLock) {
checkNotReleased();
if (mLockedObject != 0) {
throw new IllegalStateException("Surface was already locked");
}
// Native 方法调用
mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
return mCanvas;
}
}
/**
* 解锁并提交绘制结果
*/
public void unlockCanvasAndPost(Canvas canvas) {
synchronized (mLock) {
checkNotReleased();
if (mNativeObject != mLockedObject) {
throw new IllegalStateException("Surface was not locked");
}
// Native 方法调用
nativeUnlockCanvasAndPost(mNativeObject, canvas);
mLockedObject = 0;
}
}
private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
private native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty);
private native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
}
cpp
// frameworks/native/libs/gui/Surface.cpp
status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn) {
// 1. 申请图形缓冲区
sp<GraphicBuffer> backBuffer;
status_t err = dequeueBuffer(&backBuffer, ...);
if (err == NO_ERROR) {
// 2. 映射缓冲区到内存
void* mappedAddress = backBuffer->getPixels();
// 3. 创建 Canvas 所需信息
info.width = backBuffer->width;
info.height = backBuffer->height;
info.format = backBuffer->format;
info.bits = mappedAddress;
}
return err;
}
status_t Surface::unlockAndPost() {
// 1. 提交缓冲区
status_t err = queueBuffer();
// 2. 触发 SurfaceFlinger 合成
if (err == NO_ERROR) {
mClient.signalServer();
}
return err;
}
5.5 SurfaceControl 详解
java
// frameworks/base/core/java/android/view/SurfaceControl.java
public class SurfaceControl implements Parcelable {
// Native 层 SurfaceControl 指针
private long mNativeObject;
// SurfaceSession
private final SurfaceSession mSession;
// 构造函数
private SurfaceControl(SurfaceSession session, String name, int w, int h,
int format, int flags, SurfaceControl parent, int windowType,
int ownerUid) {
mSession = session;
mName = name;
// Native 方法调用
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0,
windowType, ownerUid);
}
/**
* 创建 SurfaceControl
*/
public static SurfaceControl create(SurfaceSession session, String name,
int w, int h, int format) {
return new SurfaceControl(session, name, w, h, format, 0, null, 0, 0);
}
/**
* 获取 Surface
*/
public Surface getSurface() {
if (mSurfaceControl == null) {
return null;
}
Surface surface = new Surface();
surface.copyFrom(this);
return surface;
}
private static native long nativeCreate(SurfaceSession session, String name,
int w, int h, int format, int flags, long parentObject,
int windowType, int ownerUid);
}
cpp
// frameworks/native/libs/gui/SurfaceControl.cpp
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags,
SurfaceControl* parent,
int32_t windowType,
int32_t ownerUid)
: mClient(client), mSurfaceData(0), mStatus(NO_ERROR)
{
// 1. 与 SurfaceFlinger 通信
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
// 2. 创建 Layer
status_t err = mClient->createSurface(
String8(name.c_str()),
w, h, format,
flags,
parent != NULL ? parent->mHandle : NULL,
windowType,
ownerUid,
&handle,
&gbp);
if (err == NO_ERROR) {
mHandle = handle;
mGraphicBufferProducer = gbp;
mSurfaceData = new Surface(mGraphicBufferProducer);
}
}
status_t SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags,
const sp<IBinder>& parentHandle,
int32_t windowType,
int32_t ownerUid,
sp<IBinder>* outHandle,
sp<IGraphicBufferProducer>* outGbp)
{
// 1. 通过 Binder 与 SurfaceFlinger 通信
sp<ISurfaceComposerClient> client(mClient);
// 2. 创建 Layer
return client->createSurface(
name, w, h, format, flags,
parentHandle, windowType, ownerUid,
outHandle, outGbp);
}
5.6 Surface 和 SurfaceView 的关系
scss
┌─────────────────────────────────────────────────────────────────────────┐
│ Surface 和 SurfaceView 的关系 │
└─────────────────────────────────────────────────────────────────────────┘
普通 View 场景:
┌─────────────────────────────────────────────────────────────────┐
│ PhoneWindow │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ DecorView │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ 用户布局 │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ Button │ │ TextView │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ 所有普通 View 共享同一个 Surface │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ ↓ │ │
│ │ 共享的 Surface │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
SurfaceFlinger
SurfaceView 场景:
┌─────────────────────────────────────────────────────────────────┐
│ PhoneWindow │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ DecorView │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ 用户布局 │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ Button │ │ SurfaceView │ │ │ │
│ │ │ │ (共享 Surface) │ (独立 Surface)│ │ │ │
│ │ │ └─────────────┘ └─────────────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ↓ │ │ │
│ │ │ 独立的 Surface │ │ │
│ │ │ (视频/相机专用) │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ ↓ │ │
│ │ 共享的 Surface │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
SurfaceFlinger
└─ Layer 1: 共享 Surface
└─ Layer 2: SurfaceView 独立 Surface
对比表:
| 特性 | 普通 View | SurfaceView | TextureView |
|---|---|---|---|
| Surface | 共享 Window 的 Surface | 独立的 Surface | 共享 Window 的 Surface |
| 刷新率 | 跟随屏幕刷新率 | 可独立设置刷新率 | 跟随屏幕刷新率 |
| 性能 | 一般 | 高(独立刷新) | 中等(需要纹理拷贝) |
| 使用场景 | 一般 UI | 视频、相机、游戏 | 视频、特效 |
| 缺点 | 高频刷新影响其他 UI | 可能有黑边、无法变换 | 性能开销大 |
六、SurfaceFlinger 详解
6.1 SurfaceFlinger 是什么
SurfaceFlinger 是 Android 系统服务,负责将多个 Surface(图层)合成为一个最终的显示图像。
yaml
┌─────────────────────────────────────────────────────────────────────────┐
│ SurfaceFlinger 工作原理 │
└─────────────────────────────────────────────────────────────────────────┘
输入:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Surface 1 │ │ Surface 2 │ │ Surface 3 │
│ (壁纸) │ │ (应用窗口) │ │ (状态栏) │
│ Layer: -2 │ │ Layer: 0 │ │ Layer: 10000 │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└────────────────────┴────────────────────┘
↓
┌─────────────────────┐
│ SurfaceFlinger │
│ │
│ ┌───────────────┐ │
│ │ 图层合成 │ │
│ │ Layer: 10000 │ │ ← 最上层
│ │ Layer: 0 │ │
│ │ Layer: -2 │ │ ← 最下层
│ └───────────────┘ │
│ │
│ ┌───────────────┐ │
│ │ 合成模式选择 │ │
│ │ - GPU 合成 │ │
│ │ - HWC 合成 │ │
│ └───────────────┘ │
│ │
│ ┌───────────────┐ │
│ │ 输出到屏幕 │ │
│ └───────────────┘ │
└─────────────────────┘
↓
┌─────────────────────┐
│ 屏幕显示 │
│ (最终图像) │
└─────────────────────┘
6.2 SurfaceFlinger 核心功能
| 功能 | 描述 |
|---|---|
| 图层管理 | 管理所有 Layer(Surface 的底层表示) |
| 图层合成 | 将多个 Layer 按照指定的 Z-Order 和透明度合成 |
| 硬件加速 | 支持 GPU (OpenGL ES) 和 HWC (Hardware Composer) 合成 |
| VSync 同步 | 管理垂直同步信号,协调刷新率 |
| 脏区域优化 | 只重绘变化的区域,减少功耗 |
| 多屏支持 | 管理多个显示屏的合成和输出 |
| HDR 支持 | 处理高动态范围内容 |
| 动画支持 | 支持图层变换、淡入淡出等效果 |
6.3 SurfaceFlinger 架构
scss
┌─────────────────────────────────────────────────────────────────────────┐
│ SurfaceFlinger 架构 │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ Client 层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ App 1 │ │ App 2 │ │ SystemUI │ │ ... │ │
│ │ │ │ │ │ │ │ │ │
│ │ Surface │ │ Surface │ │ Surface │ │ Surface │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
└─────────┼────────────────┼────────────────┼────────────────┼───────────┘
│ │ │ │
└────────────────┴────────────────┴────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────────┐
│ Binder IPC │
│ SurfaceComposerClient │
└─────────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────────┐
│ SurfaceFlinger (Server) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ MessageQueue │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ INVALID │ │ REFRESH │ │ CONFIG │ │ ... │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ └───────┼────────────┼────────────┼────────────┼───────────────────┘ │
│ ↓ ↓ ↓ ↓ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ EventThread │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ VSync 信号处理 │ │ │
│ │ │ - HWComposer 生成 VSync │ │ │
│ │ │ - EventThread 接收并分发 │ │ │
│ │ │ - 触发刷新 │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Layer 集合 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Layer 1 │ │ Layer 2 │ │ Layer 3 │ │ Layer N │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ └───────┼────────────┼────────────┼────────────┼───────────────────┘ │
│ ↓ ↓ ↓ ↓ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ DisplayContent │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ 显示设备管理 │ │ │
│ │ │ - 硬件渲染器 (HWComposer) │ │ │
│ │ │ - 渲染引擎 (RenderEngine) │ │ │
│ │ │ - 输出设备管理 │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 合成引擎 │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ 1. 重建图层列表 │ │ │
│ │ │ 2. 设置合成模式 │ │ │
│ │ │ 3. 执行合成 │ │ │
│ │ │ 4. 提交显示 │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────┐
│ 硬件显示设备 │
│ (HwComposer) │
└─────────────────┘
6.4 SurfaceFlinger 工作流程
cpp
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE:
handleMessageInvalidate();
break;
case MessageQueue::REFRESH:
handleMessageRefresh();
break;
}
}
/**
* 处理 INVALIDATE 消息
* 准备阶段,计算需要更新的内容
*/
void SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
// 1. 合成前的准备
preComposition();
// 2. 重建图层列表
rebuildLayerStacks();
// 3. 设置合成模式
setUpHWComposer();
}
/**
* 处理 REFRESH 消息
* 执行实际的合成操作
*/
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
// 1. 合成前的准备
preComposition();
// 2. 重建图层列表
rebuildLayerStacks();
// 3. 设置合成模式
setUpHWComposer();
// 4. 执行合成
doComposition();
// 5. 合成后处理
postComposition();
}
/**
* 合成前的准备
*/
void SurfaceFlinger::preComposition() {
// 1. 检查是否有图层需要更新
bool needExtraInvalidate = false;
// 2. 处理每个图层的动画
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
if (!displayDevice->isDisplayOn()) {
continue;
}
// 处理动画帧
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
if (layer->onPreComposition(displayDevice->getSurfaceFlinger())) {
needExtraInvalidate = true;
}
}
}
// 3. 如果需要,发送额外的 INVALIDATE 消息
if (needExtraInvalidate) {
signalLayerUpdate();
}
}
/**
* 重建图层列表
*/
void SurfaceFlinger::rebuildLayerStacks() {
// 1. 遍历所有显示设备
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
// 2. 获取可见图层
auto visibleLayers = displayDevice->getVisibleLayersSortedByZ();
// 3. 按照层排序
std::sort(visibleLayers.begin(), visibleLayers.end(),
[](const auto& lhs, const auto& rhs) {
return lhs->getSequence() < rhs->getSequence();
});
// 4. 设置到显示设备
displayDevice->setVisibleLayersSortedByZ(visibleLayers);
}
}
/**
* 设置硬件合成器
*/
void SurfaceFlinger::setUpHWComposer() {
// 1. 遍历所有显示设备
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
// 2. 获取硬件合成器
auto hwComposer = displayDevice->getHwComposer();
// 3. 设置可见图层
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
// 设置图层参数
layer->setGeometry(displayDevice, hwComposer);
layer->setPerFrameData(displayDevice, hwComposer);
}
// 4. 提交给硬件合成器
hwComposer->commit();
}
}
/**
* 执行合成
*/
void SurfaceFlinger::doComposition() {
ATRACE_CALL();
// 1. 遍历所有显示设备
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
if (!displayDevice->isDisplayOn()) {
continue;
}
// 2. 获取脏区域
const Region& dirtyRegion = displayDevice->getDirtyRegion();
// 3. 如果有脏区域,执行合成
if (!dirtyRegion.isEmpty()) {
doDisplayComposition(displayDevice, dirtyRegion);
}
// 4. 清除脏区域
displayDevice->swapBuffers();
}
}
/**
* 显示设备合成
*/
void SurfaceFlinger::doDisplayComposition(
const sp<DisplayDevice>& displayDevice,
const Region& dirtyRegion) {
// 1. 获取渲染引擎
auto renderEngine = displayDevice->getRenderEngine();
// 2. 如果使用 GPU 合成
if (displayDevice->useGpuComposition()) {
// 遍历可见图层
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
// 绘制图层
layer->draw(displayDevice, dirtyRegion, renderEngine);
}
}
// 3. 如果使用 HWC 合成
if (displayDevice->useHwcComposition()) {
// HWC 会自动处理
displayDevice->getHwComposer()->set();
}
}
/**
* 合成后处理
*/
void SurfaceFlinger::postComposition() {
ATRACE_CALL();
// 1. 处理合成后的回调
for (auto& layer : mDrawingState.layersSortedByZ) {
layer->onPostComposition();
}
// 2. 更新帧统计
mFrameTracker->setActualPresentTime(
hwComposer->getRefreshTimestamp(displayId));
// 3. 触发下一帧的 VSync
mEventThread->requestNextVsync();
}
6.5 GPU 合成 vs HWC 合成
scss
┌─────────────────────────────────────────────────────────────────────────┐
│ 合成模式对比 │
└─────────────────────────────────────────────────────────────────────────┘
GPU 合成 (OpenGL ES):
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 1 Layer 2 Layer 3 │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │ │ │ │ │ │ │
│ └───┘ └───┘ └───┘ │
│ │ │ │ │
│ └────────────┴────────────┘ │
│ ↓ │
│ ┌──────────────────┐ │
│ │ OpenGL ES │ │
│ │ GPU 合成 │ │
│ └──────────────────┘ │
│ ↓ │
│ ┌──────────────────┐ │
│ │ 合成后的 Buffer │ │
│ └──────────────────┘ │
│ ↓ │
│ ┌──────────────────┐ │
│ │ HWComposer │ │
│ │ 输出到屏幕 │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
HWC 合成 (硬件加速):
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 1 Layer 2 Layer 3 │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │ │ │ │ │ │ │
│ └───┘ └───┘ └───┘ │
│ │ │ │ │
│ ↓ ↓ ↓ │
│ ┌───────────────────────────────────────────┐ │
│ │ HWComposer │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Layer 1 │ │ Layer 2 │ │ Layer 3 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │ │
│ │ 直接由硬件合成器处理每个 Layer │ │
│ └───────────────────────────────────────────┘ │
│ ↓ │
│ 输出到屏幕 │
└─────────────────────────────────────────────────────────────────────┘
对比:
┌─────────────────────────────────────────────────────────────────────┐
│ 特性 │ GPU 合成 │ HWC 合成 │
├─────────────────────────────────────────────────────────────────────┤
│ 性能 │ 较慢 (GPU 计算) │ 更快 (硬件加速) │
│ 功耗 │ 较高 (GPU 工作) │ 更低 (专用硬件) │
│ 灵活性 │ 高 (支持任意效果) │ 低 (受硬件限制) │
│ 适用场景 │ 复杂效果、过渡动画 │ 静态或简单动画 │
│ Layer 限制 │ 无限制 │ 受硬件层限制 │
└─────────────────────────────────────────────────────────────────────┘
七、输入事件处理
7.1 输入事件处理流程
scss
┌─────────────────────────────────────────────────────────────────────────┐
│ 输入事件处理流程 │
└─────────────────────────────────────────────────────────────────────────┘
硬件设备 (触摸屏/键盘)
│
├─ 产生输入事件
│
↓
InputReader (Native)
│
├─ 读取设备事件
├─ 解析事件类型 (触摸/按键)
└─ 生成输入事件
│
↓
InputDispatcher (Native)
│
├─ 找到目标窗口
│ └─ 根据 WindowState 的 Layer 和 Touchable 区域
│
├─ 通过 InputChannel 发送事件
│
↓
ViewRootImpl (应用进程)
│
├─ InputEventReceiver 收到事件
│ └─ enqueueInputEvent()
│
├─ doProcessInputEvent()
│ └─ deliverInputEvent()
│
└─ 分发到视图树
│
├─ DecorView.dispatchTouchEvent()
│ └─ Activity.dispatchTouchEvent()
│ └─ PhoneWindow.Callback
│
└─ View.dispatchTouchEvent()
└─ 递归分发到子 View
└─ onTouchEvent()
7.2 InputChannel 创建流程
java
// frameworks/base/core/java/android/view/InputChannel.java
public final class InputChannel implements Parcelable {
private long mNativePtr; // Native 层 InputChannel 指针
/**
* 创建一对 InputChannel
* 用于服务端和客户端通信
*/
public static InputChannel[] openInputChannelPair(String name) {
return nativeOpenInputChannelPair(name);
}
private static native InputChannel[] nativeOpenInputChannelPair(String name);
}
cpp
// frameworks/native/libs/input/InputTransport.cpp
status_t InputChannel::openInputChannelPair(const String8& name,
sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
// 1. 创建 socket pair
int serverFd, clientFd;
socketpair(AF_UNIX, SOCK_SEQPACKET, 0, &serverFd, &clientFd);
// 2. 创建服务端 InputChannel
outServerChannel = new InputChannel(name, serverFd, true);
// 3. 创建客户端 InputChannel
outClientChannel = new InputChannel(name, clientFd, false);
return OK;
}
7.3 输入事件分发到窗口
java
// frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outFrame, Rect outContentInsets, Rect outStableInsets,
Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout,
InputChannel outInputChannel) {
synchronized (mGlobalLock) {
// ... 前面的代码
// 创建输入通道
if (attrs.type >= FIRST_APPLICATION_WINDOW) {
// 1. 创建 InputChannel 对
InputChannel[] inputChannels = InputChannel.openInputChannelPair(
win.toString());
// 2. 服务端通道
win.setInputChannel(inputChannels[0]);
// 3. 客户端通道传递给应用
inputChannels[1].transferTo(outInputChannel);
// 4. 注册到 InputManagerService
mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
}
// ... 后面的代码
}
}
八、窗口动画系统
8.1 WindowAnimator 详解
java
// frameworks/base/services/core/java/com/android/server/wm/WindowAnimator.java
class WindowAnimator {
final WindowManagerService mService;
final DisplayContent mDisplayContent;
/** 是否正在动画中 */
boolean mAnimating;
/** 当前动画时间 */
long mCurrentTime;
/**
* 更新窗口动画
*/
void updateWindowsLocked(boolean forceDefaultOrientation) {
// 1. 更新所有窗口动画
for (int i = mDisplayContent.windows.size() - 1; i >= 0; i--) {
WindowState w = mDisplayContent.windows.get(i);
// 2. 执行动画步骤
w.mWinAnimator.stepAnimationLocked(mCurrentTime);
}
// 3. 检查是否还有窗口在动画中
mAnimating = false;
for (int i = mDisplayContent.windows.size() - 1; i >= 0; i--) {
WindowState w = mDisplayContent.windows.get(i);
if (w.mWinAnimator.isAnimating()) {
mAnimating = true;
break;
}
}
// 4. 如果还有动画,继续请求更新
if (mAnimating) {
mService.scheduleAnimationLocked();
}
}
/**
* 执行动画
*/
boolean animateLocked(long currentTime) {
boolean wasAnimating = mAnimating;
mAnimating = false;
// 1. 更新所有窗口动画
updateWindowsLocked(false);
// 2. 更新 Surface 变换
for (int i = mDisplayContent.windows.size() - 1; i >= 0; i--) {
WindowState w = mDisplayContent.windows.get(i);
// 应用变换矩阵
if (w.mWinAnimator.mSurfaceControl != null) {
w.mWinAnimator.mSurfaceControl.setMatrix(
w.mWinAnimator.mAnimDsDx,
w.mWinAnimator.mAnimDsDy,
w.mWinAnimator.mAnimDtDx,
w.mWinAnimator.mAnimDtDy);
// 应用透明度
w.mWinAnimator.mSurfaceControl.setAlpha(
w.mWinAnimator.mAnimAlpha);
}
}
// 3. 更新屏幕
mService.scheduleAnimationLocked();
return mAnimating;
}
}
8.2 WindowStateAnimator 详解
java
// frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
class WindowStateAnimator {
final WindowState mWin;
SurfaceControl mSurfaceControl;
boolean mAnimating;
/** 动画变换参数 */
float mAnimDsDx; // Scale X
float mAnimDsDy; // Scale Y
float mAnimDtDx; // Skew X
float mAnimDtDy; // Skew Y
float mAnimAlpha; // Alpha
/** 动画 */
Animation mAnimation;
/**
* 创建 Surface
*/
void createSurfaceLocked() {
if (mSurfaceControl == null) {
// 创建 SurfaceControl
mSurfaceControl = new SurfaceControl(
mSession.mSurfaceSession,
mWin.toString(),
mWin.mAttrs.getWidth(),
mWin.mAttrs.getHeight(),
mWin.mAttrs.format,
mWin.mAttrs.flags);
}
}
/**
* 执行动画步骤
*/
void stepAnimationLocked(long currentTime) {
if (!mAnimating) return;
// 1. 如果有动画,计算动画进度
if (mAnimation != null) {
// 计算插值
float transformation = mAnimation.getTransformation(
currentTime, mTransformation);
// 获取变换参数
mAnimDsDx = mTransformation.getAlpha();
mAnimDsDy = mTransformation.getAlpha();
mAnimDtDx = mTransformation.getAlpha();
mAnimDtDy = mTransformation.getAlpha();
mAnimAlpha = mTransformation.getAlpha();
// 2. 如果动画结束
if (transformation == AnimationSet.ANIMATION_END) {
mAnimating = false;
mAnimation = null;
}
}
// 3. 应用变换到 Surface
if (mSurfaceControl != null) {
mSurfaceControl.setMatrix(mAnimDsDx, mAnimDsDy, mAnimDtDx, mAnimDtDy);
mSurfaceControl.setAlpha(mAnimAlpha);
}
}
/**
* 是否在动画中
*/
boolean isAnimating() {
return mAnimating;
}
}
8.3 窗口动画类型
| 动画类型 | 描述 | 使用场景 |
|---|---|---|
| 窗口进入 | 从无到有的动画 | Activity 打开、Dialog 显示 |
| 窗口退出 | 从有到无的动画 | Activity 关闭、Dialog 关闭 |
| 窗口切换 | 窗口之间的过渡动画 | Activity 切换 |
| 任务切换 | 任务栈切换动画 | 最近任务切换 |
| 屏幕旋转 | 屏幕方向改变动画 | 横竖屏切换 |
| 壁纸缩放 | 壁纸动画效果 | 打开应用时壁纸缩放 |
九、关键问题解答
9.1 Surface 和 SurfaceView 的关系
结论:
- Surface 是图形缓冲区的抽象容器,用于承载需要显示的图像数据
- SurfaceView 是拥有独立 Surface 的特殊 View
- 关系:SurfaceView 是 Surface 的使用者之一
| 对比项 | 普通 View | SurfaceView |
|---|---|---|
| Surface | 共享 Window 的 Surface | 独立的 Surface |
| 刷新率 | 跟随屏幕刷新率 | 可独立设置刷新率 |
| 性能 | 一般 | 高(独立刷新) |
| 使用场景 | 一般 UI | 视频、相机、游戏 |
9.2 Surface 创建时机 vs WindowState
结论:WindowState 先创建,Surface 后创建
scss
时序:
ViewRootImpl.setView()
├─ requestLayout() // T1: 请求布局(异步)
└─ addToDisplay() // T2: 添加窗口(同步)
└─ WMS.addWindow()
└─ 创建 WindowState // ← WindowState 先创建
performTraversals()
└─ relayoutWindow() // T3: 重新布局(在 addToDisplay 之后)
└─ WMS.relayoutWindow()
└─ 创建 Surface // ← Surface 后创建
9.3 Surface 创建者
结论:三方协作
- 客户端 :
ViewRootImpl通过relayoutWindow()向 WMS 请求 - 服务端 :
WindowStateAnimator调用SurfaceControl.init() - 底层 :Native 层
SurfaceComposerClient与SurfaceFlinger通信
scss
ViewRootImpl.relayoutWindow()
└─ mWindowSession.relayout()
└─ Session.relayout()
└─ WMS.relayoutWindow()
└─ WindowStateAnimator.createSurfaceLocked()
└─ SurfaceControl.init()
└─ nativeCreate()
└─ SurfaceComposerClient::createSurface()
└─ SurfaceFlinger::createLayer()
9.4 requestLayout 和 addToDisplay 执行方式
结论:顺序执行(阻塞)
java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
mWindowAttributes.copyFrom(attrs);
mView.assignParent(this);
// 1. 先执行 requestLayout - 发送异步消息
requestLayout(); // ↓ scheduleTraversals() → postCallback()
// 2. 再执行 addToDisplay - 同步阻塞调用
// 必须等 WMS 返回才能继续
res = mWindowSession.addToDisplay(...);
// 3. addToDisplay 返回后,继续执行
// 此时异步消息会在 addToDisplay 之后执行
}
}
}
为什么能保证 Surface 已就绪:
addToDisplay是同步阻塞调用,必须等 WMS 返回requestLayout发送的是异步消息,在addToDisplay之后才执行performTraversals执行时会再次调用relayoutWindow确保 Surface 已创建performTraversals内部有锁和状态检查,确保 Surface 就绪后才绘制
9.5 WindowState 具体功能
结论:WindowState 是 WMS 中窗口的核心状态管理类
| 功能 | 描述 |
|---|---|
| 窗口状态管理 | 维护窗口的显示、隐藏、焦点、可见性等状态 |
| Surface 管理 | 通过 WindowStateAnimator 管理创建、销毁、更新 |
| 布局参数管理 | 管理 LayoutParams(大小、位置、类型、标志) |
| 输入事件分发 | 创建和管理 InputChannel,分发触摸/按键事件 |
| 动画执行 | 通过 WindowStateAnimator 处理窗口动画 |
| 窗口层级管理 | 计算 Z-Order,决定窗口覆盖关系 |
| 父子关系维护 | 管理窗口之间的父子容器关系 |
| 事件回调 | 通过 IWindow.Stub 回调客户端(如焦点变化) |
9.6 SurfaceFlinger 具体功能
结论:SurfaceFlinger 是 Android 的图层合成服务
| 功能 | 描述 |
|---|---|
| 图层管理 | 管理所有 Layer(Surface 的底层表示) |
| 图层合成 | 将多个 Layer 按照指定的 Z-Order 和透明度合成 |
| 硬件加速 | 支持 GPU (OpenGL ES) 和 HWC (Hardware Composer) 合成 |
| VSync 同步 | 管理垂直同步信号,协调刷新率 |
| 脏区域优化 | 只重绘变化的区域,减少功耗 |
| 多屏支持 | 管理多个显示屏的合成和输出 |
| HDR 支持 | 处理高动态范围内容 |
| 动画支持 | 支持图层变换、淡入淡出等效果 |
9.7 DecorView 创建方式
结论:通过 XmlParser 解析 XML,通过 Factory 反射创建 View
scss
PhoneWindow.setContentView(layoutResID)
└─ installDecor()
└─ generateDecor() → 创建 DecorView 对象
LayoutInflater.inflate(layoutResID, parent)
└─ inflate(parser, root, attachToRoot)
├─ 1. XmlResourceParser 解析 XML 为事件流
├─ 2. rInflate() 递归解析 XML
├─ 3. onCreateView() 创建 View
│ └─ Factory.onCreateView() 或 Constructor.newInstance()
│ └─ ClassLoader.loadClass() + 反射实例化
└─ 4. 将 View 添加到 parent
详细流程:
java
// frameworks/base/core/java/android/view/LayoutInflater.java
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
// 1. 获取 XmlResourceParser
XmlResourceParser parser = mContext.getResources().getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
// 2. 解析 XML
final String name = parser.getName();
if (TAG_MERGE.equals(name)) {
// 处理 <merge> 标签
rInflate(parser, root, inflaterContext, attrs, false);
} else {
// 3. 创建根 View
View temp = createViewFromTag(root, name, inflaterContext, attrs);
ViewGroup.LayoutParams params = null;
if (root != null) {
// 创建 LayoutParams
params = root.generateLayoutParams(attrs);
}
// 4. 递归解析子 View
rInflateChildren(parser, temp, attrs, true);
// 5. 添加到 root
if (root != null && attachToRoot) {
root.addView(temp, params);
}
}
return result;
}
/**
* 从标签创建 View
*/
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs) {
return createView(parent, name, context, attrs, false);
}
/**
* 创建 View(通过反射)
*/
View createView(View parent, String name, Context context, AttributeSet attrs,
boolean inheritContext) {
// 1. 尝试使用 Factory 创建
if (mFactory2 != null) {
View view = mFactory2.onCreateView(parent, name, context, attrs);
if (view != null) return view;
}
if (mFactory != null) {
View view = mFactory.onCreateView(name, context, attrs);
if (view != null) return view;
}
// 2. 没有 Factory,使用反射创建
try {
// 构造函数参数
Constructor<? extends View> constructor = sConstructorMap.get(name);
if (constructor == null) {
// 获取 Class
Class<? extends View> clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);
// 获取构造函数
constructor = clazz.getConstructor(mConstructorSignature);
sConstructorMap.put(name, constructor);
}
// 创建实例
return constructor.newInstance(mConstructorArgs);
} catch (Exception e) {
// 异常处理
}
}
十、总结
10.1 核心要点
- Window 是抽象概念:PhoneWindow 是唯一实现,DecorView 是顶层视图容器
- ViewRootImpl 是桥梁:连接视图系统和 WMS,负责绘制流程
- WindowManager 是管理者:通过 Binder IPC 与 WMS 通信
- WMS 是统一管理器:管理所有窗口的显示、层级、输入事件
- Surface 是渲染目标:所有视图最终绘制到 Surface 上
- SurfaceFlinger 是合成器:将多个 Surface 合成为一个最终图像
- 三层架构:应用层 → WindowManagerImpl/Global → ViewRootImpl → WMS → SurfaceFlinger
10.2 关键流程总结
| 流程 | 关键步骤 |
|---|---|
| Window 添加 | Activity.onCreate → PhoneWindow.setContentView → Activity.onResume → WindowManager.addView → ViewRootImpl.setView → WMS.addWindow → 创建 WindowState |
| 视图绘制 | ViewRootImpl.requestLayout → scheduleTraversals → performTraversals → performMeasure → performLayout → performDraw |
| Surface 创建 | ViewRootImpl.relayoutWindow → WMS.relayoutWindow → WindowStateAnimator.createSurfaceLocked → SurfaceControl.init → SurfaceFlinger.createLayer |
| 输入事件 | InputReader → InputDispatcher → InputChannel → ViewRootImpl → DecorView.dispatchTouchEvent → View.onTouchEvent |
| 窗口动画 | WindowAnimator.animateLocked → WindowStateAnimator.stepAnimationLocked → SurfaceControl.setMatrix/setAlpha |
10.3 面试常问问题
Q1: Activity 的 setContentView 做了什么?
A:
- PhoneWindow.installDecor() 创建 DecorView
- 根据 features 选择布局文件
- 加载用户 XML 布局到 android.R.id.content 容器
Q2: View 的绘制流程?
A:
- measure() → 测量视图大小
- layout() → 确定视图位置
- draw() → 绘制视图内容
Q3: Window 和 View 的关系?
A:
- Window 是抽象概念,View 是具体组件
- Window 是 View 的容器,所有 View 必须依附于 Window
- DecorView 是 Window 的根视图
Q4: SurfaceView 和 View 的区别?
A:
- 普通 View 共享 Window 的 Surface
- SurfaceView 有自己独立的 Surface
- SurfaceView 性能更好,适合视频、相机等高频刷新场景
Q5: WMS 的作用?
A:
- 窗口管理(创建、更新、删除、显示、隐藏)
- 窗口层级管理(Z-Order)
- Surface 分配
- 输入事件分发
- 动画系统
如有问题,欢迎讨论!