当前位置: 首页 > news >正文

(笔记)Android窗口管理系统分析

概述

Android窗口管理系统是Android UI框架的核心组件,负责管理所有应用窗口的显示、布局、层级、焦点和输入事件分发。WindowManagerService(WMS)作为系统服务,协调Surface、Activity、View等组件,为用户提供流畅的界面交互体验。本文深入分析Android 7.0中的窗口管理机制,特别关注窗口焦点管理和层级系统。

窗口管理系统整体架构

┌─────────────────────────────────────────────────────────────┐
│                        用户空间                             │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐ │
│  │   Application   │  │   SystemUI      │  │   Launcher   │ │
│  │     Window      │  │    Window       │  │    Window    │ │
│  └─────────────────┘  └─────────────────┘  └─────────────┘ │
│           │                       │                       │ │
│           ▼                       ▼                       ▼ │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │                WindowManager API                        │ │
│  │        (WindowManager, ViewRootImpl)                    │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘│▼ (Binder IPC)
┌─────────────────────────────────────────────────────────────┐
│                      系统服务层                             │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │              WindowManagerService                       │ │
│  │  ┌─────────────────────────────────────────────────┐   │ │
│  │  │              焦点管理                            │   │ │
│  │  │    ┌─────────────┐ ┌─────────────────────────┐  │   │ │
│  │  │    │ 窗口焦点     │ │     应用焦点             │  │   │ │
│  │  │    │ mCurrentFocus│ │   mFocusedApp          │  │   │ │
│  │  │    └─────────────┘ └─────────────────────────┘  │   │ │
│  │  └─────────────────────────────────────────────────┘   │ │
│  │  ┌─────────────────────────────────────────────────┐   │ │
│  │  │              层级管理                            │   │ │
│  │  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │   │ │
│  │  │  │   Z-Order    │ │ WindowState │ │DisplayContent│ │   │ │
│  │  │  │   系统       │ │    管理     │ │    管理     │ │   │ │
│  │  │  └─────────────┘ └─────────────┘ └─────────────┘ │   │ │
│  │  └─────────────────────────────────────────────────┘   │ │
│  │  ┌─────────────────────────────────────────────────┐   │ │
│  │  │              输入事件分发                        │   │ │
│  │  │    InputMonitor → InputWindowHandle              │   │ │
│  │  └─────────────────────────────────────────────────┘   │ │
│  └─────────────────────────────────────────────────────────┘ │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │          WindowManagerPolicy (PhoneWindowManager)      │ │
│  │              (窗口策略和行为控制)                        │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘│▼ (Native调用)
┌─────────────────────────────────────────────────────────────┐
│                      图形系统                               │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │                  SurfaceFlinger                         │ │
│  │  ┌─────────────────────────────────────────────────┐   │ │
│  │  │              Surface合成                         │   │ │
│  │  │    ┌─────────────┐ ┌─────────────────────────┐  │   │ │
│  │  │    │   Layer     │ │    Z-Order排序           │  │   │ │
│  │  │    │   管理      │ │    硬件合成              │  │   │ │
│  │  │    └─────────────┘ └─────────────────────────┘  │   │ │
│  │  └─────────────────────────────────────────────────┘   │ │
│  └─────────────────────────────────────────────────────────┘ │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │                     Display                             │ │
│  │                  (屏幕硬件输出)                          │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

1. WindowManagerService核心架构

1.1 服务初始化和启动

文件路径: frameworks/base/services/java/com/android/server/SystemServer.java

// SystemServer中WMS的启动流程
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {// ... 其他服务初始化WindowManagerService wm = null;InputManagerService inputManager = null;try {// 先启动InputManagerServiceinputManager = new InputManagerService(context);ServiceManager.addService(Context.INPUT_SERVICE, inputManager);// 启动WindowManagerService,传入InputManagertraceBeginAndSlog("StartWindowManagerService");wm = WindowManagerService.main(context, inputManager,mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,!mFirstBoot, mOnlyCore);ServiceManager.addService(Context.WINDOW_SERVICE, wm);ServiceManager.addService(Context.INPUT_SERVICE, inputManager);Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);// 设置WindowManager与InputManager的回调关系inputManager.setWindowManagerCallbacks(wm.getInputMonitor());inputManager.start();} catch (RuntimeException e) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting core service", e);}
}

1.2 WindowManagerService类结构

文件路径: frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

/*** WindowManagerService 是 Android 窗口管理系统的核心服务类* 负责管理所有窗口的显示、布局、动画和输入事件分发等*/
public class WindowManagerService extends IWindowManager.Stubimplements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {private static final String TAG = "WindowManagerService";// === 层级管理常量 ===/** 窗口类型层级的乘数因子,用于在同类型窗口间预留z-order空间 */static final int TYPE_LAYER_MULTIPLIER = 10000;/** 用于在同层级窗口组中上下移动的偏移量 */static final int TYPE_LAYER_OFFSET = 1000;/** 窗口之间的层级间隔乘数,用于预留特效层空间 */static final int WINDOW_LAYER_MULTIPLIER = 5;/** 暗淡效果层相对目标窗口的偏移量 */static final int LAYER_OFFSET_DIM = 1;/** 动画缩略图层的偏移量 */static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER - 1;// === 核心管理对象 ===/** 当前拥有输入焦点的窗口 */WindowState mCurrentFocus = null;/** 上一次拥有焦点的窗口 */WindowState mLastFocus = null;/** 当前拥有焦点的应用Token */AppWindowToken mFocusedApp = null;/** 所有显示设备的内容管理 */private final SparseArray<DisplayContent> mDisplayContents = new SparseArray<>();/** 输入系统监听器,负责窗口与输入系统的桥接 */final InputMonitor mInputMonitor = new InputMonitor(this);/** 窗口策略管理器,控制窗口行为 */final WindowManagerPolicy mPolicy;/** Activity管理器服务接口 */final IActivityManager mActivityManager;/** 用于动画的Choreographer */final Choreographer mChoreographer = Choreographer.getInstance();// 构造函数和初始化private WindowManagerService(Context context, InputManagerService inputManager,boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {mContext = context;mHaveInputMethods = haveInputMethods;mAllowBootMessages = showBootMsgs;mOnlyCore = onlyCore;mLimitedAlphaCompositing = context.getResources().getBoolean(com.android.internal.R.bool.config_sf_limitedAlpha);mHasPermanentDpad = context.getResources().getBoolean(com.android.internal.R.bool.config_hasPermanentDpad);mInTouchMode = context.getResources().getBoolean(com.android.internal.R.bool.config_defaultInTouchMode);mInputManager = inputManager; // Must be before createDisplayContentLocked.mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);mDisplaySettings = new DisplaySettings();mDisplaySettings.readSettingsLocked();mWindowPlacerLocked = new WindowSurfacePlacer(this);mPolicy = new PhoneWindowManager();mPolicy.setWindowManagerFuncs(this);// 初始化默认显示final DisplayManager displayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);createDefaultDisplayContentLocked();// 初始化HandlermH = new H();// 启动动画线程mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper());mChoreographer = Choreographer.getInstance();}
}

2. 窗口焦点管理机制

2.1 焦点类型和概念

Android中的焦点分为两个层次:

焦点类型作用范围管理对象主要用途
应用焦点应用级别AppWindowTokenActivity切换、生命周期
窗口焦点窗口级别WindowState键盘输入、输入法

2.2 焦点管理数据结构

// WindowManagerService中的焦点管理成员
public class WindowManagerService {/** 当前拥有输入焦点的窗口 */WindowState mCurrentFocus = null;/** 上一次拥有焦点的窗口,用于焦点切换时的清理工作 */WindowState mLastFocus = null;/** 当前拥有焦点的应用,对应ActivityStack中的顶部Activity */AppWindowToken mFocusedApp = null;/** 输入法目标窗口,即当前需要输入法服务的窗口 */WindowState mInputMethodTarget = null;/** 输入法窗口,输入法应用的显示窗口 */WindowState mInputMethodWindow = null;/** 焦点更新的序列号,用于避免重复更新 */private int mFocusedDisplayId = Display.DEFAULT_DISPLAY;
}// WindowState中的焦点相关属性
public final class WindowState implements WindowManagerPolicy.WindowState {/** 窗口是否可以获得焦点 */boolean mCanReceiveKeys = false;/** 窗口当前是否拥有焦点 */boolean mHasFocus = false;/** 窗口的焦点观察者列表 */private final RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks = new RemoteCallbackList<IWindowFocusObserver>();/** 该窗口是否在焦点搜索中被考虑 */public boolean canReceiveKeys() {return isVisibleOrAdding()&& (mViewVisibility == View.VISIBLE) && !mRemoveOnExit&& ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)&& (mAppToken == null || mAppToken.windowsAreFocusable())&& !mAnimatingExit;}
}

2.3 焦点更新流程

// 焦点更新的核心方法
public class WindowManagerService {/*** 更新焦点窗口* @param mode 更新模式:UPDATE_FOCUS_NORMAL, UPDATE_FOCUS_WILL_ASSIGN_LAYERS等* @param updateInputWindows 是否同时更新输入窗口* @return 如果焦点发生变化返回true*/boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Updating focused window...");WindowState newFocus = computeFocusedWindowLocked();if (mCurrentFocus != newFocus) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");// 备份旧焦点final WindowState oldFocus = mCurrentFocus;mCurrentFocus = newFocus;// 更新亮度updateBrightnessLocked();// 通知焦点变化if (newFocus != null) {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "New focus: " + newFocus);newFocus.reportFocusChangedSerialized(true, mInTouchMode);notifyFocusChanged();}if (oldFocus != null) {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Lost focus: " + oldFocus);oldFocus.reportFocusChangedSerialized(false, mInTouchMode);}// 更新输入法目标if (mode == UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {// 延迟到layer分配完成后更新mInputMethodTarget = null;} else if (mode == UPDATE_FOCUS_PLACING_SURFACES) {// 在surface放置期间更新updateInputMethodTargetLocked(mInputMethodTarget);} else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {// 准备放置surface时更新// 延迟处理} else {// 正常模式,立即更新输入法目标updateInputMethodTargetLocked(null);}Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);return true;}return false;}/*** 计算应该获得焦点的窗口* 按照Z-order从上到下搜索可获得焦点的窗口*/private WindowState computeFocusedWindowLocked() {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Computing focused window...");final DisplayContent displayContent = getDefaultDisplayContentLocked();WindowState result = null;WindowState candidate = null;// 遍历所有窗口,从最上层开始for (int i = displayContent.mWindows.size() - 1; i >= 0; i--) {WindowState win = displayContent.mWindows.get(i);if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Looking for focus: " + win + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys());if (!win.canReceiveKeys()) {continue;}AppWindowToken wtoken = win.mAppToken;// 如果这是一个应用窗口if (wtoken != null) {// 检查应用是否允许窗口获得焦点if (!wtoken.windowsAreFocusable()) {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "App windows not focusable: " + wtoken);continue;}// 如果应用正在显示启动窗口,跳过if (wtoken.mAppAnimator.freezingScreen) {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "App freezing: " + wtoken);continue;}// 找到候选窗口if (candidate == null) {candidate = win;}}// 如果找到系统窗口或者合适的应用窗口,立即返回if (wtoken == null || candidate == win) {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Found focus: " + win);return win;}}return candidate;}/*** 通知焦点变化给相关系统组件*/private void notifyFocusChanged() {// 通知AccessibilityManagerif (mAccessibilityController != null) {mAccessibilityController.onWindowFocusChangedLocked();}// 通知InputMethodManagerif (mCurrentFocus != null) {mInputMonitor.setInputFocusLocked(mCurrentFocus, updateInputWindows);}}
}// WindowState中的焦点通知
public final class WindowState {/*** 报告焦点变化给应用程序*/void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) {try {mClient.windowFocusChanged(focused, inTouchMode);} catch (RemoteException e) {// 客户端进程可能已经死亡}// 通知焦点观察者if (mFocusCallbacks != null) {final int N = mFocusCallbacks.beginBroadcast();for (int i = 0; i < N; i++) {IWindowFocusObserver obs = mFocusCallbacks.getBroadcastItem(i);try {if (focused) {obs.focusGained(mWindowId.asBinder());} else {obs.focusLost(mWindowId.asBinder());}} catch (RemoteException e) {// 观察者可能已经死亡}}mFocusCallbacks.finishBroadcast();}}
}

2.4 焦点与输入法的协作

public class WindowManagerService {/*** 更新输入法目标窗口* 输入法目标是当前需要输入法服务的窗口*/boolean updateInputMethodTargetLocked(WindowState targetWin) {WindowState newTarget = null;if (targetWin == null) {// 重新计算输入法目标newTarget = computeInputMethodTargetLocked();} else {newTarget = targetWin;}if (DEBUG_INPUT_METHOD) {Slog.v(TAG_WM, "Proposed new IME target: " + newTarget);}// 检查目标是否发生变化if (mInputMethodTarget == newTarget) {return false;}if (newTarget != null) {AppWindowToken token = newTarget.mAppToken;if (token != null) {// 检查应用是否准备好接收输入法if (token.mAppAnimator.freezingScreen) {newTarget = null;}}}if (DEBUG_INPUT_METHOD) {Slog.v(TAG_WM, "Final new IME target: " + newTarget);Slog.v(TAG_WM, "Last IME target: " + mInputMethodTarget);}if (newTarget == mInputMethodTarget) {return false;}final WindowState oldTarget = mInputMethodTarget;mInputMethodTarget = newTarget;// 通知输入法管理器if (mInputMethodManager != null) {mInputMethodManager.updateInputMethodTargetLocked(oldTarget, newTarget);}return true;}/*** 计算输入法目标窗口* 通常是当前焦点窗口,但也考虑特殊情况*/private WindowState computeInputMethodTargetLocked() {// 首先检查当前焦点窗口if (mCurrentFocus != null && mCurrentFocus.canReceiveKeys() &&!mCurrentFocus.mAttrs.isModal()) {return mCurrentFocus;}// 如果焦点窗口是模态的,寻找其父窗口WindowState target = mCurrentFocus;while (target != null) {if (target.canBeImeTarget()) {return target;}target = target.mParentWindow;}// 最后的备选方案return null;}
}

3. 窗口层级管理系统

3.1 Z-Order层级体系

Android窗口系统使用多层次的Z-Order管理:

// 窗口类型的基础层级定义
public class WindowManagerPolicy {// 应用窗口层级(1-99)public static final int APPLICATION_LAYER = 2;public static final int APPLICATION_MEDIA_OVERLAY_LAYER = APPLICATION_LAYER - 1;public static final int APPLICATION_MEDIA_LAYER = APPLICATION_LAYER - 2;public static final int APPLICATION_PANEL_SUBLAYER = 1;public static final int APPLICATION_SUB_PANEL_SUBLAYER = 2;public static final int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;// 系统窗口层级(2000+)public static final int PHONE_LAYER = 3;public static final int SEARCH_BAR_LAYER = 4;public static final int SYSTEM_DIALOG_LAYER = 5;public static final int TOAST_LAYER = 6;public static final int PRIORITY_PHONE_LAYER = 7;public static final int SYSTEM_ALERT_LAYER = 8;public static final int SYSTEM_ERROR_LAYER = 9;public static final int INPUT_METHOD_LAYER = 10;public static final int INPUT_METHOD_DIALOG_LAYER = 11;public static final int KEYGUARD_LAYER = 12;public static final int KEYGUARD_DIALOG_LAYER = 13;public static final int STATUS_BAR_SUB_PANEL_LAYER = 14;public static final int STATUS_BAR_LAYER = 15;public static final int STATUS_BAR_PANEL_LAYER = 16;public static final int NOTIFICATION_PANEL_LAYER = 17;public static final int SYSTEM_OVERLAY_LAYER = 18;public static final int SECURE_SYSTEM_OVERLAY_LAYER = 19;public static final int DRAG_LAYER = 20;public static final int ACCESSIBILITY_OVERLAY_LAYER = 21;public static final int BOOT_PROGRESS_LAYER = 22;public static final int POINTER_LAYER = 23;public static final int UNIVERSE_BACKGROUND_LAYER = 1;
}

3.2 层级计算算法

public class WindowManagerService {/*** 为窗口分配层级值* 层级值决定了窗口在Z轴上的位置*/final int assignLayersLocked(WindowList windows) {if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based on windows=" + windows);int N = windows.size();int curBaseLayer = 0;int curLayer = 0;int i;if (DEBUG_LAYERS) {RuntimeException here = new RuntimeException("here");here.fillInStackTrace();Slog.v(TAG_WM, "Assigning layers", here);}boolean anyLayerChanged = false;for (i = 0; i < N; i++) {final WindowState w = windows.get(i);final WindowStateAnimator winAnimator = w.mWinAnimator;boolean layerChanged = false;int oldLayer = w.mLayer;if (w.mBaseLayer == curBaseLayer || w.mIsImWindow ||(i > 0 && w.mIsWallpaper)) {curLayer += WINDOW_LAYER_MULTIPLIER;w.mLayer = curLayer;} else {curBaseLayer = curLayer = w.mBaseLayer;w.mLayer = curLayer;}if (w.mLayer != oldLayer) layerChanged = true;if (w.mTargetAppToken != null) {winAnimator.mAnimLayer = w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;} else if (w.mAppToken != null) {winAnimator.mAnimLayer = w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;} else {winAnimator.mAnimLayer = w.mLayer;}if (w.mIsImWindow) {winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;} else if (w.mIsWallpaper) {winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;}if (layerChanged) {anyLayerChanged = true;setLayoutNeeded();}if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assign layer " + w + ": "+ "mBase=" + w.mBaseLayer+ " mLayer=" + w.mLayer+ (w.mAppToken == null ?"" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)+ " =mAnimLayer=" + winAnimator.mAnimLayer);}//TODO (multidisplay): Magnification is supported only for the default display.if (mAccessibilityController != null && anyLayerChanged &&windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {mAccessibilityController.onWindowLayersChangedLocked();}return curLayer;}/*** 获取窗口类型对应的基础层级*/public int getBaseLayerLocked(WindowState win) {int baseLayer = mPolicy.windowTypeToLayerLw(win.mAttrs.type) * TYPE_LAYER_MULTIPLIER+ TYPE_LAYER_OFFSET;if (DEBUG_LAYERS) Slog.v(TAG_WM, "Base layer: " + baseLayer+ " for " + win + " type " + win.mAttrs.type);return baseLayer;}
}// PhoneWindowManager中的窗口类型到层级的映射
public class PhoneWindowManager implements WindowManagerPolicy {public int windowTypeToLayerLw(int type) {if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {return APPLICATION_LAYER;}switch (type) {case TYPE_PRIVATE_PRESENTATION:return APPLICATION_LAYER;case TYPE_WALLPAPER:return UNIVERSE_BACKGROUND_LAYER;case TYPE_PHONE:return PHONE_LAYER;case TYPE_SEARCH_BAR:return SEARCH_BAR_LAYER;case TYPE_VOICE_INTERACTION:return VOICE_INTERACTION_LAYER;case TYPE_SYSTEM_DIALOG:return SYSTEM_DIALOG_LAYER;case TYPE_TOAST:return TOAST_LAYER;case TYPE_PRIORITY_PHONE:return PRIORITY_PHONE_LAYER;case TYPE_SYSTEM_ALERT:return SYSTEM_ALERT_LAYER;case TYPE_SYSTEM_ERROR:return SYSTEM_ERROR_LAYER;case TYPE_INPUT_METHOD:return INPUT_METHOD_LAYER;case TYPE_INPUT_METHOD_DIALOG:return INPUT_METHOD_DIALOG_LAYER;case TYPE_KEYGUARD_SCRIM:return KEYGUARD_SCRIM_LAYER;case TYPE_STATUS_BAR_SUB_PANEL:return STATUS_BAR_SUB_PANEL_LAYER;case TYPE_STATUS_BAR:return STATUS_BAR_LAYER;case TYPE_STATUS_BAR_PANEL:return STATUS_BAR_PANEL_LAYER;case TYPE_KEYGUARD_DIALOG:return KEYGUARD_DIALOG_LAYER;case TYPE_VOLUME_OVERLAY:return VOLUME_OVERLAY_LAYER;case TYPE_SYSTEM_OVERLAY:return SYSTEM_OVERLAY_LAYER;case TYPE_NAVIGATION_BAR:return NAVIGATION_BAR_LAYER;case TYPE_NAVIGATION_BAR_PANEL:return NAVIGATION_BAR_PANEL_LAYER;case TYPE_SCREENSHOT:return SCREENSHOT_LAYER;case TYPE_SECURE_SYSTEM_OVERLAY:return SECURE_SYSTEM_OVERLAY_LAYER;case TYPE_DRAG:return DRAG_LAYER;case TYPE_ACCESSIBILITY_OVERLAY:return ACCESSIBILITY_OVERLAY_LAYER;case TYPE_MAGNIFICATION_OVERLAY:return MAGNIFICATION_OVERLAY_LAYER;case TYPE_DISPLAY_OVERLAY:return DISPLAY_OVERLAY_LAYER;case TYPE_POINTER:return POINTER_LAYER;}Log.e(TAG, "Unknown window type: " + type);return APPLICATION_LAYER;}
}

3.3 窗口层级示例

Z-Order从上到下的典型窗口层级:23000: TYPE_POINTER (鼠标指针)
22000: TYPE_BOOT_PROGRESS (启动进度)
21000: TYPE_ACCESSIBILITY_OVERLAY (无障碍覆盖层)
20000: TYPE_DRAG (拖拽层)
19000: TYPE_SECURE_SYSTEM_OVERLAY (安全系统覆盖层)
18000: TYPE_SYSTEM_OVERLAY (系统覆盖层)
17000: TYPE_NOTIFICATION_PANEL (通知面板)
16000: TYPE_STATUS_BAR_PANEL (状态栏面板)
15000: TYPE_STATUS_BAR (状态栏)
14000: TYPE_STATUS_BAR_SUB_PANEL (状态栏子面板)
13000: TYPE_KEYGUARD_DIALOG (锁屏对话框)
12000: TYPE_KEYGUARD (锁屏)
11000: TYPE_INPUT_METHOD_DIALOG (输入法对话框)
10000: TYPE_INPUT_METHOD (输入法)9000: TYPE_SYSTEM_ERROR (系统错误)8000: TYPE_SYSTEM_ALERT (系统警告)7000: TYPE_PRIORITY_PHONE (优先级电话)6000: TYPE_TOAST (Toast提示)5000: TYPE_SYSTEM_DIALOG (系统对话框)4000: TYPE_SEARCH_BAR (搜索栏)3000: TYPE_PHONE (电话)2000: TYPE_APPLICATION (普通应用窗口)└── 2015: 应用窗口3 (最上层应用窗口)└── 2010: 应用窗口2└── 2005: 应用窗口1 (最下层应用窗口)1000: TYPE_UNIVERSE_BACKGROUND (壁纸)

4. WindowState窗口状态管理

4.1 WindowState核心属性

文件路径: frameworks/base/services/core/java/com/android/server/wm/WindowState.java

public final class WindowState implements WindowManagerPolicy.WindowState {static final String TAG = "WindowState";// === 基本属性 ===/** 窗口管理服务引用 */final WindowManagerService mService;/** 窗口会话,对应客户端进程 */final Session mSession;/** 客户端窗口接口 */final IWindow mClient;/** 窗口令牌,用于权限检查和分组 */final WindowToken mToken;/** 应用令牌,如果是应用窗口的话 */AppWindowToken mAppToken;/** 窗口布局参数 */final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();// === 层级和位置 ===/** 窗口的基础层级 */int mBaseLayer;/** 窗口的实际层级 */int mLayer;/** 窗口在父容器中的子层级 */int mSubLayer = 0;/** 窗口的显示框架 */final Rect mDisplayFrame = new Rect();/** 窗口的父框架 */final Rect mParentFrame = new Rect();/** 窗口的内容插入区域 */final Rect mContentInsets = new Rect();/** 窗口的可见插入区域 */final Rect mVisibleInsets = new Rect();/** 窗口的稳定插入区域(不包括临时UI元素) */final Rect mStableInsets = new Rect();// === 焦点和输入 ===/** 窗口是否可以接收按键事件 */boolean mCanReceiveKeys = false;/** 窗口当前是否拥有焦点 */boolean mHasFocus = false;/** 输入通道,用于接收输入事件 */InputChannel mInputChannel;/** 输入窗口句柄,用于InputDispatcher */final InputWindowHandle mInputWindowHandle;// === 可见性和动画 ===/** 客户端报告的可见性 */int mViewVisibility;/** 系统确定的可见性 */boolean mPolicyVisibility = true;/** 是否正在退出动画 */boolean mAnimatingExit = false;/** 是否已经被移除 */boolean mRemoveOnExit = false;/** 窗口的Surface */SurfaceControl mSurfaceControl;/** 窗口状态动画器 */final WindowStateAnimator mWinAnimator;// === 父子关系 ===/** 父窗口 */WindowState mParentWindow;/** 子窗口列表 */final WindowList mChildWindows = new WindowList();// 构造函数WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,int viewVisibility, final DisplayContent displayContent) {mService = service;mSession = s;mClient = c;mToken = token;mParentWindow = parentWindow;mAppOp = appOp;mSeq = seq;mAttrs.copyFrom(a);mViewVisibility = viewVisibility;mDisplayContent = displayContent;mPolicy = mService.mPolicy;mContext = mService.mContext;// 创建动画器mWinAnimator = new WindowStateAnimator(this);mWinAnimator.mAlpha = a.alpha;// 创建输入句柄mInputWindowHandle = new InputWindowHandle(mAppToken != null ? mAppToken.mInputApplicationHandle : null, this,displayContent.getDisplayId());}/*** 检查窗口是否可以接收按键事件*/public boolean canReceiveKeys() {return isVisibleOrAdding()&& (mViewVisibility == View.VISIBLE) && !mRemoveOnExit&& ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)&& (mAppToken == null || mAppToken.windowsAreFocusable())&& !mAnimatingExit;}/*** 检查窗口是否可见或正在添加*/boolean isVisibleOrAdding() {final AppWindowToken atoken = mAppToken;return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))&& mPolicyVisibility && !mAttachedHidden&& (atoken == null || !atoken.hiddenRequested)&& !mAnimatingExit && !mDestroying;}/*** 检查窗口是否可以成为输入法目标*/boolean canBeImeTarget() {if (mIsImWindow) {// 输入法窗口本身不能成为目标return false;}final boolean windowsAreFocusable = mAppToken == null || mAppToken.windowsAreFocusable();if (!windowsAreFocusable) {// 如果应用窗口不可聚焦,则不能成为输入法目标return false;}final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);if (fl != 0 && fl != FLAG_ALT_FOCUSABLE_IM) {return false;}if (DEBUG_INPUT_METHOD) {Slog.i(TAG_WM, "isVisibleOrAdding " + this + ": " + isVisibleOrAdding());if (!isVisibleOrAdding()) {Slog.i(TAG_WM, "  mSurface=" + mWinAnimator.mSurfaceControl+ " relayoutCalled=" + mRelayoutCalled + " viewVis=" + mViewVisibility+ " policyVis=" + mPolicyVisibility + " attachHid=" + mAttachedHidden+ " exiting=" + mAnimatingExit + " destroying=" + mDestroying);if (mAppToken != null) {Slog.i(TAG_WM, "  mAppToken.hiddenRequested=" + mAppToken.hiddenRequested);}}}return isVisibleOrAdding();}
}

4.2 窗口生命周期管理

public class WindowManagerService {/*** 添加窗口到系统*/public int addWindow(Session session, IWindow client, int seq,WindowManager.LayoutParams attrs, int viewVisibility, int displayId,Rect outContentInsets, Rect outStableInsets, Rect outOutsets,InputChannel outInputChannel) {int[] appOp = new int[1];int res = mPolicy.checkAddPermission(attrs, appOp);if (res != WindowManagerGlobal.ADD_OKAY) {return res;}boolean reportNewConfig = false;WindowState parentWindow = null;long origId;final int type = attrs.type;synchronized(mWindowMap) {if (!mDisplayReady) {throw new IllegalStateException("Display has not been initialialized");}final DisplayContent displayContent = getDisplayContentLocked(displayId);if (displayContent == null) {Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "+ displayId + ".  Aborting.");return WindowManagerGlobal.ADD_INVALID_DISPLAY;}if (mWindowMap.containsKey(client.asBinder())) {Slog.w(TAG_WM, "Window " + client + " is already added");return WindowManagerGlobal.ADD_DUPLICATE_ADD;}if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {parentWindow = windowForClientLocked(null, attrs.token, false);if (parentWindow == null) {Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "+ attrs.token + ".  Aborting.");return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;}if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW&& parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "+ attrs.token + ".  Aborting.");return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;}}// 创建窗口令牌WindowToken token = displayContent.getWindowToken(attrs.token);AppWindowToken atoken = null;boolean addToastWindowRequiresToken = false;if (token == null) {if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {Slog.w(TAG_WM, "Attempted to add application window with unknown token "+ attrs.token + ".  Aborting.");return WindowManagerGlobal.ADD_BAD_APP_TOKEN;}if (type == TYPE_INPUT_METHOD) {Slog.w(TAG_WM, "Attempted to add input method window with unknown token "+ attrs.token + ".  Aborting.");return WindowManagerGlobal.ADD_BAD_APP_TOKEN;}// 创建新的窗口令牌token = new WindowToken(this, attrs.token, -1, false);addToastWindowRequiresToken = true;} else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {atoken = token.appWindowToken;if (atoken == null) {Slog.w(TAG_WM, "Attempted to add window with non-application token "+ token + ".  Aborting.");return WindowManagerGlobal.ADD_NOT_APP_TOKEN;} else if (atoken.removed) {Slog.w(TAG_WM, "Attempted to add window with exiting application token "+ token + ".  Aborting.");return WindowManagerGlobal.ADD_APP_EXITING;}}// 创建WindowStatefinal WindowState win = new WindowState(this, session, client, token,parentWindow, appOp[0], seq, attrs, viewVisibility, displayContent);if (win.mDeathRecipient == null) {// 客户端已经死亡Slog.w(TAG_WM, "Adding window client " + client.asBinder()+ " that is dead, aborting.");return WindowManagerGlobal.ADD_APP_EXITING;}if (win.getDisplayContent() == null) {Slog.w(TAG_WM, "Adding window to Display that has been removed.");return WindowManagerGlobal.ADD_INVALID_DISPLAY;}// 检查权限mPolicy.adjustWindowParamsLw(win.mAttrs);win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));res = mPolicy.prepareAddWindowLw(win, attrs);if (res != WindowManagerGlobal.ADD_OKAY) {return res;}// 创建输入通道final boolean openInputChannels = (outInputChannel != null&& (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);if  (openInputChannels) {win.openInputChannel(outInputChannel);}// 添加到窗口映射mWindowMap.put(client.asBinder(), win);if (win.mAppOp != AppOpsManager.OP_NONE) {int startOpResult = mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(),win.getOwningPackage());if ((startOpResult != AppOpsManager.MODE_ALLOWED) &&(startOpResult != AppOpsManager.MODE_DEFAULT)) {win.setAppOpVisibilityLw(false);}}// 添加到显示内容win.attach();mWindowMap.put(client.asBinder(), win);// 更新焦点boolean focusChanged = false;if (win.canReceiveKeys()) {focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,false /*updateInputWindows*/);if (focusChanged) {imMayMove = false;}}// 分配层级assignLayersLocked(displayContent.getWindowList());if (focusChanged) {mInputMonitor.setInputFocusLocked(mCurrentFocus, false /*updateInputWindows*/);}mInputMonitor.updateInputWindowsLocked(false /*force*/);return WindowManagerGlobal.ADD_OKAY;}}/*** 移除窗口*/void removeWindowLocked(WindowState win) {if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "removeWindowLocked: " + win);win.disposeInputChannel();if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,"Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl+ " mExiting=" + win.mAnimatingExit);final long origId = Binder.clearCallingIdentity();win.disposeInputChannel();if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,"Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl+ " mExiting=" + win.mAnimatingExit);// 清理资源if (win.mAppOp != AppOpsManager.OP_NONE) {mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());}mWindowMap.remove(win.mClient.asBinder());if (mInputMethodTarget == win) {moveInputMethodWindowsIfNeededLocked(false);}win.mToken.removeWindow(win);if (win.mAppToken != null) {win.mAppToken.removeWindow(win);}mPendingRemove.remove(win);mResizingWindows.remove(win);mWindowsChanged = true;if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win);if (mInputMethodWindow == win) {mInputMethodWindow = null;} else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {mInputMethodDialogs.remove(win);}final WindowToken token = win.mToken;final AppWindowToken atoken = win.mAppToken;if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token);if (token.isEmpty()) {if (!token.explicit) {token.removeAllWindows();} else if (atoken != null) {atoken.firstWindowDrawn = false;atoken.clearAllDrawn();}}if (atoken != null) {if (atoken.startingWindow == win) {if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling startingWindow " + win);atoken.startingWindow = null;} else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {// 如果这是最后一个窗口,并且有待显示的启动窗口,取消它if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,"Schedule remove starting " + token+ ": no more real windows");scheduleRemoveStartingWindowLocked(atoken);}}boolean changed = false;if (win == mCurrentFocus) {if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused window: " + win);changed = updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);}if (win == mInputMethodTarget) {setInputMethodTargetLocked(null);}win.onRemovedFromDisplay();Binder.restoreCallingIdentity(origId);}
}

5. 输入事件分发机制

5.1 InputMonitor事件分发

final class InputMonitor implements InputManagerService.WindowManagerCallbacks {private final WindowManagerService mService;// 输入窗口句柄数组,用于InputDispatcherprivate final ArrayList<InputWindowHandle> mInputWindowHandles = new ArrayList<InputWindowHandle>();// 当前拥有输入焦点的窗口句柄private InputWindowHandle mInputFocus;public InputMonitor(WindowManagerService service) {mService = service;}/*** 更新输入窗口信息,发送给InputDispatcher*/public void updateInputWindowsLocked(boolean force) {if (!force && !mUpdateInputWindowsNeeded) {return;}mUpdateInputWindowsNeeded = false;if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLocked");// 清空现有窗口句柄mInputWindowHandles.clear();final ArrayList<WindowState> windows = mService.mWindows;for (int i = windows.size() - 1; i >= 0; i--) {final WindowState child = windows.get(i);final InputChannel inputChannel = child.mInputChannel;final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;if (inputChannel == null || inputWindowHandle == null || child.mRemoved) {// 跳过没有输入通道或已移除的窗口continue;}final int flags = child.mAttrs.flags;final int privateFlags = child.mAttrs.privateFlags;final int type = child.mAttrs.type;final boolean hasFocus = (child == mInputFocus);final boolean isVisible = child.isVisibleLw();final boolean hasWallpaper = (child == mService.mWallpaperTarget);// 添加窗口到输入窗口句柄列表addInputWindowHandleLw(inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);}// 发送输入窗口信息给InputManagermService.mInputManager.setInputWindows(mInputWindowHandles.toArray(new InputWindowHandle[mInputWindowHandles.size()]));if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLocked");}/*** 添加输入窗口句柄*/private void addInputWindowHandleLw(final InputWindowHandle windowHandle,final WindowState child, final int flags, final int type,final boolean isVisible, final boolean hasFocus, final boolean hasWallpaper) {// 设置输入窗口属性windowHandle.name = child.toString();windowHandle.layoutParamsFlags = flags;windowHandle.layoutParamsType = type;windowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();windowHandle.visible = isVisible;windowHandle.canReceiveKeys = child.canReceiveKeys();windowHandle.hasFocus = hasFocus;windowHandle.hasWallpaper = hasWallpaper;windowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;windowHandle.layer = child.mLayer;windowHandle.ownerPid = child.mSession.mPid;windowHandle.ownerUid = child.mSession.mUid;windowHandle.inputFeatures = child.mAttrs.inputFeatures;final Rect frame = child.mFrame;windowHandle.frameLeft = frame.left;windowHandle.frameTop = frame.top;windowHandle.frameRight = frame.right;windowHandle.frameBottom = frame.bottom;if (child.mGlobalScale != 1) {// 如果有缩放,应用缩放变换windowHandle.scaleFactor = child.mGlobalScale;} else {windowHandle.scaleFactor = 1;}// 设置触摸区域if (child.mTouchableInsets == ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION) {windowHandle.touchableRegion.set(child.mGivenTouchableRegion);windowHandle.touchableRegion.translate(child.mFrame.left, child.mFrame.top);} else {windowHandle.touchableRegion.set(frame);if (child.mTouchableInsets == ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {windowHandle.touchableRegion.op(child.mGivenContentInsets.left + child.mFrame.left,child.mGivenContentInsets.top + child.mFrame.top,child.mFrame.right - child.mGivenContentInsets.right,child.mFrame.bottom - child.mGivenContentInsets.bottom,Region.Op.INTERSECT);} else if (child.mTouchableInsets == ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {windowHandle.touchableRegion.op(child.mGivenVisibleInsets.left + child.mFrame.left,child.mGivenVisibleInsets.top + child.mFrame.top,child.mFrame.right - child.mGivenVisibleInsets.right,child.mFrame.bottom - child.mGivenVisibleInsets.bottom,Region.Op.INTERSECT);}}mInputWindowHandles.add(windowHandle);}/*** 设置输入焦点*/public void setInputFocusLocked(WindowState newWindow, boolean updateInputWindows) {if (DEBUG_FOCUS_LIGHT) {Slog.d(TAG_WM, "Input focus has changed to " + newWindow);}if (newWindow != mInputFocus) {if (newWindow != null && newWindow.canReceiveKeys()) {// 通知InputManager新的焦点窗口newWindow.mToken.paused = false;}mInputFocus = newWindow;setUpdateInputWindowsNeededLocked();if (updateInputWindows) {updateInputWindowsLocked(false /*force*/);}}}
}

5.2 窗口触摸区域计算

public final class WindowState {/*** 计算窗口的触摸区域*/void getTouchableRegion(Region outRegion) {final Rect frame = mFrame;switch (mTouchableInsets) {default:case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:outRegion.set(frame);break;case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:outRegion.set(frame);outRegion.op(frame.left + mGivenContentInsets.left,frame.top + mGivenContentInsets.top,frame.right - mGivenContentInsets.right,frame.bottom - mGivenContentInsets.bottom, Region.Op.INTERSECT);break;case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:outRegion.set(frame);outRegion.op(frame.left + mGivenVisibleInsets.left,frame.top + mGivenVisibleInsets.top,frame.right - mGivenVisibleInsets.right,frame.bottom - mGivenVisibleInsets.bottom, Region.Op.INTERSECT);break;case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {final Region givenTouchableRegion = mGivenTouchableRegion;outRegion.set(givenTouchableRegion);outRegion.translate(frame.left, frame.top);break;}}cropRegionToStackBoundsIfNeeded(outRegion);}/*** 裁剪区域到栈边界*/private void cropRegionToStackBoundsIfNeeded(Region region) {final Task task = getTask();if (task == null || !task.cropWindowsToStackBounds()) {return;}final TaskStack stack = task.mStack;if (stack == null) {return;}stack.getDimBounds(mTmpRect);region.op(mTmpRect, Region.Op.INTERSECT);}
}

6. SurfaceFlinger集成

6.1 Surface与Layer管理

public class WindowStateAnimator {final WindowState mWin;final WindowManagerService mService;final WindowManagerPolicy mPolicy;final Context mContext;final Session mSession;/*** Surface控制器,用于与SurfaceFlinger通信*/SurfaceControl mSurfaceControl;/*** 窗口的动画层级*/int mAnimLayer;/*** 窗口的基础层级*/int mLastLayer;/*** 创建Surface*/SurfaceControl createSurfaceLocked() {if (mSurfaceControl == null) {if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,"createSurface " + this + ": mDrawState=DRAW_PENDING");mDrawState = DRAW_PENDING;if (mWin.mAppToken != null) {mWin.mAppToken.allDrawn = false;mWin.mAppToken.deferClearAllDrawn = false;}mService.makeWindowFreezingScreenIfNeededLocked(mWin);int flags = SurfaceControl.HIDDEN;final WindowManager.LayoutParams attrs = mWin.mAttrs;if (mService.isSecureLocked(mWin)) {flags |= SurfaceControl.SECURE;}int width, height;if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {// 缩放窗口width = (int) (mWin.mRequestedWidth * mWin.mGlobalScale + 0.5f);height = (int) (mWin.mRequestedHeight * mWin.mGlobalScale + 0.5f);} else {width = mWin.mRequestedWidth;height = mWin.mRequestedHeight;}// 确保尺寸至少为1x1if (width < 1) width = 1;if (height < 1) height = 1;final boolean isHwAccelerated = (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;if (DEBUG_SURFACE_TRACE) {mSurfaceControl = new SurfaceControlWithBackground(mSession.mSurfaceSession,attrs.getTitle().toString(),width, height, format, flags,mWin.mOwnerUid);} else {mSurfaceControl = new SurfaceControl(mSession.mSurfaceSession,attrs.getTitle().toString(),width, height, format, flags,mWin.mOwnerUid);}mWin.mHasSurface = true;if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,"  CREATE SURFACE "+ mSurfaceControl + " IN SESSION "+ mSession.mSurfaceSession+ ": pid=" + mSession.mPid + " format="+ attrs.format + " flags=0x"+ Integer.toHexString(flags)+ " / " + this);} else {mWin.mHasSurface = true;}return mSurfaceControl;}/*** 设置Layer层级*/void setLayerLocked(SurfaceControl.Transaction t, int layer) {if (mSurfaceControl != null) {mLastLayer = layer;if (SHOW_TRANSACTIONS) Slog.i(TAG, "  SURFACE LAYER " + layer + ": " + this);t.setLayer(mSurfaceControl, layer);}}/*** 设置窗口位置*/void setPositionLocked(SurfaceControl.Transaction t, float left, float top) {final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;if (surfaceMoved) {mSurfaceX = left;mSurfaceY = top;try {if (SHOW_TRANSACTIONS) Slog.i(TAG, "  SURFACE POS " + left + ", " + top + ": " + this);t.setPosition(mSurfaceControl, left, top);} catch (RuntimeException e) {Slog.w(TAG, "Error setting surface position", e);}}}
}

7. 性能优化和调试

7.1 窗口管理性能监控

性能指标监控方法优化目标
焦点切换延迟Trace.traceBegin/End< 16ms
层级分配时间assignLayersLocked耗时< 8ms
Surface创建时间createSurfaceLocked耗时< 32ms
输入窗口更新updateInputWindowsLocked< 4ms
布局计算时间performLayoutAndPlaceSurfaces< 16ms

7.2 调试开关和日志

// WindowManagerDebugConfig.java中的调试开关
public class WindowManagerDebugConfig {static final boolean DEBUG = false;static final boolean DEBUG_FOCUS = false;           // 焦点调试static final boolean DEBUG_FOCUS_LIGHT = false;     // 轻量级焦点调试static final boolean DEBUG_LAYERS = false;          // 层级调试static final boolean DEBUG_INPUT_METHOD = false;    // 输入法调试static final boolean DEBUG_LAYOUT = false;          // 布局调试static final boolean DEBUG_SURFACE_TRACE = false;   // Surface跟踪static final boolean DEBUG_WINDOW_MOVEMENT = false; // 窗口移动调试static final boolean DEBUG_ADD_REMOVE = false;      // 添加/移除调试
}// 关键调试日志示例
if (DEBUG_FOCUS_LIGHT) {Slog.v(TAG_WM, "Updating focused window: old=" + mCurrentFocus + " new=" + newFocus);
}if (DEBUG_LAYERS) {Slog.v(TAG_WM, "Assign layer " + win + ": mBase=" + win.mBaseLayer + " mLayer=" + win.mLayer + " =mAnimLayer=" + winAnimator.mAnimLayer);
}

7.3 内存和资源管理

public class WindowManagerService {/*** 执行垃圾回收和资源清理*/public void performGarbageCollection() {synchronized (mWindowMap) {// 清理死亡的窗口cleanupDeadWindows();// 清理无用的Application TokencleanupAppTokens();// 清理Surface资源cleanupSurfaces();// 请求系统GCRuntime.getRuntime().gc();}}/*** 清理死亡的窗口*/private void cleanupDeadWindows() {final ArrayList<WindowState> deadWindows = new ArrayList<>();// 查找死亡的窗口for (int i = mWindowMap.size() - 1; i >= 0; i--) {WindowState win = mWindowMap.valueAt(i);if (win.mSession.mClient == null || !win.mSession.mClient.asBinder().isBinderAlive()) {deadWindows.add(win);}}// 移除死亡的窗口for (WindowState win : deadWindows) {Slog.w(TAG_WM, "Force-removing dead window: " + win);removeWindowLocked(win);}}/*** 监控内存使用情况*/public void dumpMemoryUsage(PrintWriter pw) {pw.println("Window Manager Memory Usage:");pw.println("  Window count: " + mWindowMap.size());pw.println("  Token count: " + mTokenMap.size());// 统计Surface内存使用long surfaceMemory = 0;for (WindowState win : mWindowMap.values()) {if (win.mWinAnimator.mSurfaceControl != null) {surfaceMemory += win.mRequestedWidth * win.mRequestedHeight * 4; // 假设RGBA}}pw.println("  Estimated surface memory: " + (surfaceMemory / 1024) + " KB");}
}

8. 总结

8.1 WindowManager核心价值

  1. 统一窗口管理: 提供所有UI元素的统一管理接口
  2. 智能焦点分配: 基于Z-order和策略的智能焦点管理
  3. 精确层级控制: 细粒度的窗口层级和显示控制
  4. 高效事件分发: 与输入系统深度集成的事件分发
  5. 资源协调: Surface、动画、输入等资源的协调管理

8.2 架构设计优势

  • 分层架构: 清晰的服务层、策略层、渲染层分离
  • 策略驱动: WindowManagerPolicy提供灵活的行为定制
  • 异步处理: Handler机制确保UI线程不被阻塞
  • 资源复用: 高效的Surface和输入通道管理
  • 调试友好: 完善的日志和调试机制

8.3 系统协作机制

WindowManagerService作为系统UI的核心协调者:

  • 与ActivityManager: 应用生命周期和任务管理
  • 与InputManager: 输入事件的精确分发
  • 与SurfaceFlinger: 图形渲染和合成
  • 与PackageManager: 应用权限和配置管理

相关文件路径

核心服务文件

  • frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java - 窗口管理服务主实现
  • frameworks/base/services/core/java/com/android/server/wm/WindowState.java - 窗口状态管理
  • frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java - 窗口动画管理

策略和配置

  • frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java - 手机窗口策略
  • frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java - 显示内容管理
  • frameworks/base/services/core/java/com/android/server/wm/WindowToken.java - 窗口令牌管理

输入集成

  • frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java - 输入事件监控
  • frameworks/base/services/core/java/com/android/server/input/InputWindowHandle.java - 输入窗口句柄

客户端接口

  • frameworks/base/core/java/android/view/WindowManager.java - 窗口管理器接口
  • frameworks/base/core/java/android/view/ViewRootImpl.java - 视图根实现
  • frameworks/base/core/java/android/view/WindowManagerGlobal.java - 全局窗口管理
http://www.dtcms.com/a/355863.html

相关文章:

  • 向量方法证明正余弦定理的数学理论体系
  • 如何保证数据的安全性和隐私性?
  • Spring Boot + KingbaseES 连接池实战
  • TypeScript:枚举类型
  • Milvus向量数据库是什么?
  • Active Directory Basics
  • UPAM(Unified Prompt Attack Model
  • 应急响应/windows权限维持/Linux权限维持
  • 虚拟机逃逸攻防演练:从攻击模拟到隔离漏洞防御实战
  • 机器学习回顾(二)——KNN算法
  • 【Cadence技巧】立创EDA/Altium/Allegro之间的封装转换
  • layout版图设计学习笔记2_工艺流程
  • 切入高潜市场,抢占行业先机!ES SHOW 2025展位预订火爆,10月28-30日共启增长新蓝海
  • php姓名三才五格api接口调用说明
  • 疯狂星期四文案网第53天运营日记
  • gdbserver远程调试和交叉编译gdb
  • Fuzzy Multimodal Learning for Trusted Cross-modal Retrieval(CVPR 2025)
  • OpenCV 图像操作进阶:像素、边界与融合技术
  • 数据结构青铜到王者第九话---二叉树(2)
  • 多语言与零样本语音识别新突破:基于发音特征分类的方法
  • 通过ETL工具,同步SQLserver数据至starrocks数据库
  • Autosar之DCM模块
  • 构建AI智能体:十六、构建本地化AI应用:基于ModelScope与向量数据库的文本向量化
  • Day14 Gorm框架学习(1)
  • 安装与环境搭建:准备你的 Electron 开发环境
  • leetcode 525 连续数组
  • 可改善能源利用水平、削减碳排放总量,并为可再生能源规模化发展提供有力支撑的智慧能源开源了
  • 计算机组成原理3-3-5:定点数的乘法运算——补码阵列乘法器
  • init.usb.configfs.rc的USB动态配置
  • 算法学习笔记:双指针_滑动窗口专题