Android framework学习笔记 -- 原生分屏原理

分屏代码在AOSP其实老早就存在了,就一直没有开启而已,在6.0版本可以通过设置系统属性ro.build.type改为userdebug,并在开发者选项中开启多窗口模式,然后在最近任务上就会个按钮可以实现分屏。

通过adb命令也可以实现分屏

$ am task resize 25 0 720 1080 1920

在最近任务的调用链

RecentsActivity#onTaskResize ->
RecentsResizeTaskDialog#placeTasks ->
SystemServicesProxy#resizeTask -> 
ActivityManagerNative#resizeTask -> 
ActivityManagerService#resizeTask -> 
ActivityStackSupervisor#resizeStackLocked

在am的调用链

Am#runTaskResize-> 
ActivityManagerNative#resizeTask -> 
ActivityManagerService#resizeTask -> 
ActivityStackSupervisor#resizeTaskLocked

ActivityStackSupervisor的实现

foundStackWithBounds
ActivityStackSupervisor#moveTaskToStackLocked ->
ActivityStackSupervisor#resizeStackLocked

ActivityStackSupervisor#moveTaskToStackLocked - > 
WindowManagerService#moveTaskToStack

ActivityStackSupervisor#resizeStackLocked ->
WindowManagerService#resizeStack

WindowManagerService的实现

WindowManagerService#resizeStack ->
TaskStack#setBounds
TaskStack#resizeWindows ->
updateLayout??



























看来让人心情不好的乱七八糟源码分析

//---> frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void resizeTaskLocked(TaskRecord task, Rect bounds) {
    task.mResizeable = true;
    final ActivityStack currentStack = task.stack;
    if (currentStack.isHomeStack()) {
        // Can't move task off the home stack. Sorry!
        return;
    }

    // 找到给定区域相同的栈
    final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds);
    if (matchingStackId != -1) {
        // There is already a stack with the right bounds!
        if (currentStack != null && 
                    currentStack.mStackId == matchingStackId) {
            // Nothing to do here. Already in the right stack...
            return;
        }
        // Move task to stack with matching bounds.
        moveTaskToStackLocked(task.taskId, matchingStackId, true);
        return;
    }

    // 栈里只有一个task,直接resize栈
    if (currentStack != null && currentStack.numTasks() == 1) {
        // Just resize the current stack since this is the task in it.
        resizeStackLocked(currentStack.mStackId, bounds);
        return;
    }

    // 挪动task到新的栈
    // Create new stack and move the task to it.
    final int displayId = 
            (currentStack != null && currentStack.mDisplayId != -1)
            ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY;
    ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId);

    if (newStack == null) {
        Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task);
        return;
    }
    moveTaskToStackLocked(task.taskId, newStack.mStackId, true);
    resizeStackLocked(newStack.mStackId, bounds);
}

分屏的核心是task跟bound,需要看一下task是怎么裂变的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值