新Activity启动时Task的位置(分屏场景)

目录

场景

在这里插入图片描述

当类似上面的Task状态,我们自定义的三个按钮,启动新的Activity的时候,并没有去设置需要launche的task。

 		Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.android.dialer",
                    "com.android.dialer.main.impl.MainActivity"));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
            startActivity(intent);

但是直接启动后windowmode和task都是展示正常的,并没有像普通launcher启动App后的全屏展示。
在这里插入图片描述
经过源码查看,其实就是会直接使用sourceTask的往上寻找mCreatedByOrganizer的Task
TaskDisplayArea.java

  // If a task is launching from a created-by-organizer task, it should be launched into the
        // same created-by-organizer task as well. Unless, the candidate task is already positioned
        // in the another adjacent task.
        if (sourceTask != null) {
            Task launchTarget = sourceTask.getCreatedByOrganizerTask();
            if (launchTarget != null && launchTarget.getAdjacentTaskFragment() != null) {
                if (candidateTask != null) {
                    final Task candidateRoot = candidateTask.getCreatedByOrganizerTask();
                    if (candidateRoot != null && candidateRoot != launchTarget
                            && launchTarget == candidateRoot.getAdjacentTaskFragment()) {
                        launchTarget = candidateRoot;
                    }
                }
                return launchTarget;
            }
        }

Task.java

   /** @return the first create-by-organizer task. */
    @Nullable
    Task getCreatedByOrganizerTask() {
        if (mCreatedByOrganizer) {
            return this;
        }
        final WindowContainer parent = getParent();
        if (parent == null) {
            return null;
        }
        final Task parentTask = parent.asTask();
        return parentTask == null ? null : parentTask.getCreatedByOrganizerTask();
    }

那么这个类型的task是什么时候初始化的呢,经过查找
StageCoordinator.java

StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
            ShellTaskOrganizer taskOrganizer, DisplayController displayController,
            DisplayImeController displayImeController,
            DisplayInsetsController displayInsetsController, Transitions transitions,
            TransactionPool transactionPool, SplitscreenEventLogger logger,
            IconProvider iconProvider, ShellExecutor mainExecutor,
            Optional<RecentTasksController> recentTasks,
            Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
        mContext = context;
        mDisplayId = displayId;
        mSyncQueue = syncQueue;
        mTaskOrganizer = taskOrganizer;
        mLogger = logger;
        mMainExecutor = mainExecutor;
        mRecentTasks = recentTasks;
        mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
        mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
        //初始化分屏的roottask
        taskOrganizer.createRootTask(displayId, WINDOWING_MODE_FULLSCREEN, this /* listener */);
		//初始化上下分屏的task, new的时候会去创建task,然后回调回来拿到taskinfo
        mMainStage = new MainStage(
                mContext,
                mTaskOrganizer,
                mDisplayId,
                mMainStageListener,
                mSyncQueue,
                mSurfaceSession,
                iconProvider,
                mMainUnfoldController);
        mSideStage = new SideStage(
                mContext,
                mTaskOrganizer,
                mDisplayId,
                mSideStageListener,
                mSyncQueue,
                mSurfaceSession,
                iconProvider,
                mSideUnfoldController);
        mDisplayController = displayController;
        mDisplayImeController = displayImeController;
        mDisplayInsetsController = displayInsetsController;
        mTransactionPool = transactionPool;
        final DeviceStateManager deviceStateManager =
                mContext.getSystemService(DeviceStateManager.class);
        deviceStateManager.registerCallback(taskOrganizer.getExecutor(),
                new DeviceStateManager.FoldStateListener(mContext, this::onFoldedStateChanged));
        mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
                this::onTransitionAnimationComplete, this);
        mDisplayController.addDisplayWindowListener(this);
        mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
        transitions.addHandler(this);
    }

这里跨进程创建的task就是mCreatedByOrganizer==true的类型了

    @VisibleForTesting
    Task createRootTask(DisplayContent display, int windowingMode, @Nullable IBinder launchCookie) {
        ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create root task displayId=%d winMode=%d",
                display.mDisplayId, windowingMode);
        // We want to defer the task appear signal until the task is fully created and attached to
        // to the hierarchy so that the complete starting configuration is in the task info we send
        // over to the organizer.
        final Task task = new Task.Builder(mService)
                .setWindowingMode(windowingMode)
                .setIntent(new Intent())
                .setCreatedByOrganizer(true)
                .setDeferTaskAppear(true)
                .setLaunchCookie(launchCookie)
                .setParent(display.getDefaultTaskDisplayArea())
                .build();
        task.setDeferTaskAppear(false /* deferTaskAppear */);
        return task;
    }

可以看一下层级结构树
原始

#1 Task=6 type=standard mode=multi-window override-mode=multi-window requested-bounds=[0,1498][1440,2960] bounds=[0,1498][1440,2960]
          #0 Task=183 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
           #0 ActivityRecord{fa1ec4b u0 com.android.launcher3/.SplitScreenActivity} t183} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
            #0 5dffcd4 com.android.launcher3/com.android.launcher3.SplitScreenActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
         #0 Task=5 type=standard mode=multi-window override-mode=multi-window requested-bounds=[0,0][1440,1463] bounds=[0,0][1440,1463]
          #0 Task=182 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,1463]
           #0 ActivityRecord{49e57de u0 com.android.messaging/.ui.conversationlist.ConversationListActivity} t182} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,1463]
            #0 72fe958 com.android.messaging/com.android.messaging.ui.conversationlist.ConversationListActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,1463]

启动新的后

#1 Task=6 type=standard mode=multi-window override-mode=multi-window requested-bounds=[0,1498][1440,2960] bounds=[0,1498][1440,2960]
          #1 Task=184 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
           #0 ActivityRecord{2d84183 u0 com.android.dialer/.main.impl.MainActivity} t184} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
            #0 72a75f4 com.android.dialer/com.android.dialer.main.impl.MainActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
          #0 Task=183 type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
           #0 ActivityRecord{fa1ec4b u0 com.android.launcher3/.SplitScreenActivity} t183} type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]
            #0 5dffcd4 com.android.launcher3/com.android.launcher3.SplitScreenActivity type=standard mode=multi-window override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,1498][1440,2960]

由此可以简单总结,在需要启动新的Task的情况下,会查找organizer创建的task,如果不需要就直接ActivityRecord挂载了,至于organizer创建的task特性可以看注释。


/**
     * This TaskFragment was created by an organizer which has the following implementations.
     * <ul>
     *     <li>The TaskFragment won't be removed when it is empty. Removal has to be an explicit
     *     request from the organizer.</li>
     *     <li>If this fragment is a Task object then unlike other non-root tasks, it's direct
     *     children are visible to the organizer for ordering purposes.</li>
     *     <li>A TaskFragment can be created by {@link android.window.TaskFragmentOrganizer}, and
     *     a Task can be created by {@link android.window.TaskOrganizer}.</li>
     * </ul>
     */

可以看到这类型的task是就孩子算是空也不会被移除,Launcher桌面直接启动的时候可以挂载的parent就是TaskDisplayArea了,和这里分屏的情况又有所区别,也就解释了分屏情况或者在桌面都直接启动的情况下,task位置和bound都显示正常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值