Activity栈管理 -- 多窗口模式

354 阅读3分钟

​一、核心架构与类定义

Android 14的多窗口管理已完全重构为​​基于层级容器(WindowContainer)的树形结构​​,核心类如下:

RootWindowContainer

源码路径​​:frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

​职责​​:全局窗口层级树的根容器,管理所有物理/虚拟屏幕(DisplayContent

​关键属性​​:

mWindowManagerServer :与WMS关联

mDisplays: 所有屏幕的实例

Task

源码路径​​:frameworks/base/services/core/java/com/android/server/wm/Task.java

​职责​​: 替代旧版ActivityStack,管理一组ActivityRecord,支持动态调整边界(mBounds)

​关键方法​​:

`
//设置窗口物理区域
@Override
public int setBounds(Rect bounds) {
    if (isRootTask()) {
        return setBounds(getRequestedOverrideBounds(), bounds);
    }

    int rotation = Surface.ROTATION_0;
    final DisplayContent displayContent = getRootTask() != null
            ? getRootTask().getDisplayContent() : null;
    if (displayContent != null) {
        rotation = displayContent.getDisplayInfo().rotation;
    }

    final int boundsChange = super.setBounds(bounds);
    mRotation = rotation;
    updateSurfacePositionNonOrganized();
    return boundsChange;
}`

`/**
 * @param reason The reason for moving the root task to the front.
 * @param task If non-null, the task will be moved to the top of the root task.
 */
@VisibleForTesting
void moveToFront(String reason, Task task) {
    if (!isAttached()) {
        return;
    }
    mTransitionController.recordTaskOrder(this);

    final TaskDisplayArea taskDisplayArea = getDisplayArea();

    if (!isActivityTypeHome() && returnsToHomeRootTask()) {
        // Make sure the root home task is behind this root task since that is where we
        // should return to when this root task is no longer visible.
        taskDisplayArea.moveHomeRootTaskToFront(reason + " returnToHome");
    }

    final Task lastFocusedTask = isRootTask() ? taskDisplayArea.getFocusedRootTask() : null;
    if (task == null) {
        task = this;
    }
    task.getParent().positionChildAt(POSITION_TOP, task, true /* includingParents */);
    taskDisplayArea.updateLastFocusedRootTask(lastFocusedTask, reason);
}`

ActivityRecord

​源码路径​​:frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java

​职责​​:记录单个Activity的元数据及运行时状态,直接绑定WMS的WindowToken

​关键属性​​:

`Task mTask; // 所属Task
int mDisplayId; // 所在屏幕ID
ActivityState mState; // 生命周期状态(RESUMED/PAUSED等)`

​**​` ActivityTaskSupervisor​​

​`源码路径​​:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java

​职责​​:协调跨进程Activity启动、生命周期切换及多窗口栈迁移

​关键逻辑​​:

`void startActivity(); // 处理Intent解析和栈决策
void resumeFocusedTasksTopActivities(); // 触发焦点栈顶Activity的RESUME`

二、多窗口模式下的栈管理机制​​

​1. 分屏模式(Split-Screen)​

​实现原理​​:

​栈拆分​​:通过SplitScreenController将屏幕划分为两个DisplayArea,每个区域绑定独立Task

​源码流程​​:

`// SplitScreenController.java
void splitPrimaryTask(Task primaryTask, Rect leftBounds, Rect rightBounds) {
    // 创建新DisplayArea
    DisplayArea.Tokens leftArea = createDisplayArea(leftBounds);
    DisplayArea.Tokens rightArea = createDisplayArea(rightBounds);
    // 迁移Task至指定区域
    primaryTask.reparent(leftArea);
    secondaryTask.reparent(rightArea);
}`

​生命周期规则​​:

仅焦点栈顶Activity处于RESUMED状态,非焦点栈顶Activity为PAUSED但可见

​状态同步​​:通过ActivityTaskSupervisor.handlePauseActivity()和handleResumeActivity()跨进程同步

​2. 自由窗口模式(Freeform)​

​动态调整​​:

   ​**​窗口拖拽​**​:WindowManagerService通过WindowContainerTransaction更新Task.mBounds

​边界生效​​:触发Task.onConfigurationChanged(),通知应用重布局

​启动参数​​:

`// 通过ActivityOptions指定初始尺寸
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchBounds(new Rect(0, 0, 800, 600));`

​3.画中画模式​

​栈管理​​:

PinnedTaskController管理PINNED_STACK_ID栈,强制Z轴置顶

窗口合成:SurfaceFlinger通过LayerState标记PIP窗口为LAYER_PIP

​​进入流程​​:

// ActivityRecord.java
void enterPictureInPictureMode() {
    mAtmService.moveActivityToPinnedStack(mToken); // 迁移至PIP栈
}

三、 关键流程和源码交互​​

​1. Activity 启动与栈决策​

​启动决策树​

图片.png

​源码锚点​​:

 ActivityStarter.execute()处理Flag和Affinity匹配

RootWindowContainer.getOrCreateTask()创建/复用Task

​2. 窗口层级合成​

​​Z轴计算​​:

    WindowLayersController.assignLayer()根据Task.mLayer和窗口类型排序

​关键逻辑​​:

`// WindowLayersController.java
void assignLayers(WindowContainer root) {
    for (WindowContainer child : root.getChildren()) {
        child.assignLayer(this);
    }
}`

四、调试与验证​​

​1. 关键调试命令(Android 14生效)​

`# 查看所有Task及ActivityRecord
adb shell dumpsys activity containers
# 显示窗口层级与Z轴顺序
adb shell dumpsys window windows
# 查看特定Task的边界信息
adb shell dumpsys activity task <task_id>`

​2. 源码验证点 ​

图片.png

总结

Android 14的多窗口栈管理基于​​层级容器树(WindowContainer)​​,通过RootWindowContainer协调全局层级,Task实现动态边界控制,ActivityTaskSupervisor处理跨进程调度。开发者需重点关注:

​​容器树操作​​:DisplayContent与Task的reparent()逻辑

​​状态同步机制​​:ActivityRecord.mState与WMS的WindowState强绑定 ​​调试工具链​​:结合dumpsys命令与源码断点(如ActivityTaskSupervisor.resumeFocusedTasksTopActivities())验证行为