Android 13 分割画面の分割線ドラッグ処理のソースコード解析

こんにちは。前のセクションでは分割画面の起動プロセスを分析しました。このセクションでは、分割画面の使用中に分割線をドラッグするプロセスを紹介します。

1. 分割線のドラッグ部分

B局無料動画チュートリアル解説:
https://www.bilibili.com/video/BV1wj411o7A9/
ここに画像の説明を挿入
ドラッグした分割線のDividerViewのonTouchを見てください

    public boolean onTouch(View v, MotionEvent event) {
    
    
        if (mSplitLayout == null || !mInteractive) {
    
    
            return false;
        }

        if (mDoubleTapDetector.onTouchEvent(event)) {
    
    
            return true;
        }

        // Convert to use screen-based coordinates to prevent lost track of motion events while
        // moving divider bar and calculating dragging velocity.
        event.setLocation(event.getRawX(), event.getRawY());
        final int action = event.getAction() & MotionEvent.ACTION_MASK;
        final boolean isLandscape = isLandscape();
        final int touchPos = (int) (isLandscape ? event.getX() : event.getY());
        switch (action) {
    
    
            case MotionEvent.ACTION_DOWN:
                mVelocityTracker = VelocityTracker.obtain();
                mVelocityTracker.addMovement(event);
                setTouching();
                mStartPos = touchPos;
                mMoving = false;
                break;
            case MotionEvent.ACTION_MOVE:
                mVelocityTracker.addMovement(event);
                if (!mMoving && Math.abs(touchPos - mStartPos) > mTouchSlop) {
    
    
                    mStartPos = touchPos;
                    mMoving = true;
                }
                if (mMoving) {
    
    
                    final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
                    mSplitLayout.updateDivideBounds(position);//最重要的拖动方法
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                releaseTouching();
                if (!mMoving) break;

                mVelocityTracker.addMovement(event);
                mVelocityTracker.computeCurrentVelocity(1000 /* units */);
                final float velocity = isLandscape
                        ? mVelocityTracker.getXVelocity()
                        : mVelocityTracker.getYVelocity();
                final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
                final DividerSnapAlgorithm.SnapTarget snapTarget =
                        mSplitLayout.findSnapTarget(position, velocity, false /* hardDismiss */);
                mSplitLayout.snapToTarget(position, snapTarget);//松手后要进行动画,DividerView自动到某个区域
                mMoving = false;
                break;
        }

        return true;
    }

ここでは、mSplitLayout.updateDivideBounds(position) メソッドに焦点を当てます。

    /**
     * Updates bounds with the passing position. Usually used to update recording bounds while
     * performing animation or dragging divider bar to resize the splits.
     */
    void updateDivideBounds(int position) {
    
    
        updateBounds(position);//更新一下bound区域
        mSplitLayoutHandler.onLayoutSizeChanging(this);
        //会调用对应的onLayoutSizeChanging方法来负责通知size变化了
    }

   @Override
    public void onLayoutSizeChanging(SplitLayout layout) {
    
    
        final SurfaceControl.Transaction t = mTransactionPool.acquire();
        t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
        setResizingSplits(true /* resizing */);
        updateSurfaceBounds(layout, t, true /* applyResizingOffset */);//会把对应的DividerView进行坐标更新,实现跟手
        mMainStage.onResizing(getMainStageBounds(), t);//通知主屏幕,告知有size变化,如果bounds变大则显示icon+背景,否则显示原来内容,并控制内容的区域跟随divideriew位置
        mSideStage.onResizing(getSideStageBounds(), t);//通知次屏幕,告知有size变化,如果bounds变大则显示icon+背景,否则显示原来内容,并控制内容的区域跟随divideriew位置
        t.apply();
        mTransactionPool.release(t);
    }
       void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t,
            boolean applyResizingOffset) {
    
    
        final StageTaskListener topLeftStage =
                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
        final StageTaskListener bottomRightStage =
                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
                //这里关键调用了applySurfaceChanges
        (layout != null ? layout : mSplitLayout).applySurfaceChanges(t, topLeftStage.mRootLeash,
                bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer,
                applyResizingOffset);
    }

applySurfaceChanges メソッドを見てみましょう。

public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1,
            SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2,
            boolean applyResizingOffset) {
    
    
        final SurfaceControl dividerLeash = getDividerLeash();
        if (dividerLeash != null) {
    
    
            mTempRect.set(getRefDividerBounds());
            t.setPosition(dividerLeash, mTempRect.left, mTempRect.top);
            //这里是设置DeviderView进行位置设置
            // Resets layer of divider bar to make sure it is always on top.
            t.setLayer(dividerLeash, Integer.MAX_VALUE);
        }
        mTempRect.set(getRefBounds1());
        t.setPosition(leash1, mTempRect.left, mTempRect.top)//设置上下分屏的位置和裁减
                .setWindowCrop(leash1, mTempRect.width(), mTempRect.height());
        mTempRect.set(getRefBounds2());
        t.setPosition(leash2, mTempRect.left, mTempRect.top)
                .setWindowCrop(leash2, mTempRect.width(), mTempRect.height());

        if (mImePositionProcessor.adjustSurfaceLayoutForIme(
                t, dividerLeash, leash1, leash2, dimLayer1, dimLayer2)) {
    
    
            return;
        }

        mSurfaceEffectPolicy.adjustDimSurface(t, dimLayer1, dimLayer2);//进行对应的特效显示,拉到底部或之顶部进行灰度提示
        if (applyResizingOffset) {
    
    
            mSurfaceEffectPolicy.adjustRootSurface(t, leash1, leash2);
        }
    }

次に、mMainStage.onResizing メソッドを確認します。


 /** Showing resizing hint. */
    public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds,
            SurfaceControl.Transaction t) {
    
    
   //省略
   //这里本质就是判断是否该区域有变大,如果有变大则变成ICON+背景,另一个屏则保持原样,因为show是为false
        final boolean show =
                newBounds.width() > mBounds.width() || newBounds.height() > mBounds.height();
 			//省略
        t.setPosition(mIconLeash,
                newBounds.width() / 2 - mIconSize / 2,
                newBounds.height() / 2 - mIconSize / 2);

        if (animate) {
    
    //启动相关显示的动画
            startFadeAnimation(show, false /* isResized */);
            mShown = show;
        }
    }

ここに画像の説明を挿入

DividerViewをドラッグして座標を移動し、スタックを設定します


setPosition:2964, SurfaceControl$Transaction (android.view)
applySurfaceChanges:508, SplitLayout (com.android.wm.shell.common.split)
updateSurfaceBounds:1286, StageCoordinator (com.android.wm.shell.splitscreen)
onLayoutSizeChanging:1233, StageCoordinator (com.android.wm.shell.splitscreen)
updateDivideBounds:358, SplitLayout (com.android.wm.shell.common.split)
onTouch:298, DividerView (com.android.wm.shell.common.split)
dispatchTouchEvent:15000, View (android.view)
dispatchTransformedTouchEvent:3115, ViewGroup (android.view)
dispatchTouchEvent:2788, ViewGroup (android.view)
dispatchPointerEvent:15263, View (android.view)
processPointerEvent:6548, ViewRootImpl$ViewPostImeInputStage (android.view)
onProcess:6348, ViewRootImpl$ViewPostImeInputStage (android.view)
deliver:5804, ViewRootImpl$InputStage (android.view)
onDeliverToNext:5861, ViewRootImpl$InputStage (android.view)
forward:5827, ViewRootImpl$InputStage (android.view)
forward:5992, ViewRootImpl$AsyncInputStage (android.view)
apply:5835, ViewRootImpl$InputStage (android.view)
apply:6049, ViewRootImpl$AsyncInputStage (android.view)
deliver:5808, ViewRootImpl$InputStage (android.view)
onDeliverToNext:5861, ViewRootImpl$InputStage (android.view)
forward:5827, ViewRootImpl$InputStage (android.view)
apply:5835, ViewRootImpl$InputStage (android.view)
deliver:5808, ViewRootImpl$InputStage (android.view)
deliverInputEvent:8857, ViewRootImpl (android.view)
doProcessInputEvents:8808, ViewRootImpl (android.view)
enqueueInputEvent:8777, ViewRootImpl (android.view)
onInputEvent:8980, ViewRootImpl$WindowInputEventReceiver (android.view)
dispatchInputEvent:267, InputEventReceiver (android.view)
nativeConsumeBatchedInputEvents:-1, InputEventReceiver (android.view)
consumeBatchedInputEvents:247, InputEventReceiver (android.view)
doConsumeBatchedInput:8937, ViewRootImpl (android.view)
run:9071, ViewRootImpl$ConsumeBatchedInputRunnable (android.view)
run:1231, Choreographer$CallbackRecord (android.view)
run:1239, Choreographer$CallbackRecord (android.view)
doCallbacks:899, Choreographer (android.view)
doFrame:824, Choreographer (android.view)
run:1214, Choreographer$FrameDisplayEventReceiver (android.view)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7897, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

2. 手を離した後の移動アニメーションとタスクの領域設定

上記ですでに知られているように、これは主に、手放した後に mSplitLayout.snapToTarget(position, snapTarget) によって実行されます。

  /**
     * Sets new divide position and updates bounds correspondingly. Notifies listener if the new
     * target indicates dismissing split.
     */
    public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) {
    
    
        switch (snapTarget.flag) {
    
    
            case FLAG_DISMISS_START:
                flingDividePosition(currentPosition, snapTarget.position,
                        () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */));
                break;
            case FLAG_DISMISS_END:
                flingDividePosition(currentPosition, snapTarget.position,
                        () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */));
                break;
            default:
                flingDividePosition(currentPosition, snapTarget.position,
                        () -> setDividePosition(snapTarget.position, true /* applyLayoutChange */));
                break;
        }
    }

ここで FLAG_DISMISS_START と FLAG_DISMISS_END について説明します。
FLAG_DISMISS_START: 以下の図に示すように、DividerView が上にスライドし、上部の分割画面が終了することを意味します。
ここに画像の説明を挿入

FLAG_DISMISS_END: 次の分割画面がシーンから出るまで下にスライドすることを表します

多くの状況があることがわかりますが、それらはすべて flingDividePosition を呼び出しますが、最終的なコールバック メソッドは異なります。ここでは通常、デフォルトの状況を使用します。

 @VisibleForTesting
    void flingDividePosition(int from, int to, @Nullable Runnable flingFinishedCallback) {
    
    
        if (from == to) {
    
    
            // No animation run, still callback to stop resizing.
            mSplitLayoutHandler.onLayoutSizeChanged(this);
            return;
        }
        InteractionJankMonitorUtils.beginTracing(InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE,
                mSplitWindowManager.getDividerView(), "Divider fling");
        ValueAnimator animator = ValueAnimator
                .ofInt(from, to)
                .setDuration(250);//开始设置动画,一个from一个to作为开始和截至地方
        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        animator.addUpdateListener(
                animation -> updateDivideBounds((int) animation.getAnimatedValue()));
        animator.addListener(new AnimatorListenerAdapter() {
    
    
            @Override
            public void onAnimationEnd(Animator animation) {
    
    
            //动画结束以后的最重要的操作,需要真正的windowcontainer的bounds进行操作了
                if (flingFinishedCallback != null) {
    
    
                    flingFinishedCallback.run();//执行传递进来的那个runable
                }
                InteractionJankMonitorUtils.endTracing(
                        InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
    
    
                setDividePosition(to, true /* applyLayoutChange */);
            }
        });
        animator.start();
    }

ここでの重要なポイントは、アニメーションの実行が完了した後に setDividePosition メソッドを呼び出すことです。

  void setDividePosition(int position, boolean applyLayoutChange) {
    
    
        mDividePosition = position;
        updateBounds(mDividePosition);
        if (applyLayoutChange) {
    
    
            mSplitLayoutHandler.onLayoutSizeChanged(this);
        }
    }

この setDividePosition についてはhttps://blog.csdn.net/learnframework/article/details/130944230で説明されており
、最後に対応する境界が systemserver のタスクに設定されます。

3. systemserver の終了原理

systemui 側の呼び出し状況を確認してください。

フレームワーク/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java

 private void applyExitSplitScreen(@Nullable StageTaskListener childrenToTop,
            WindowContainerTransaction wct, @ExitReason int exitReason) {
    
    
       //省略
        final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP;
        mSideStage.removeAllTasks(wct, !fromEnteringPip && mSideStage == childrenToTop);//移除对应的sidestate下面task节点,其实本质就是把子节点进行对应的reparent到新的父亲
        mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop);//其实和上面的removeAllTask类似,都是对task进行reparent操作,不能再继续挂载在分屏的节点了
        
        //对分屏的总节点进行对应的reorder,放到后面了,不能到最前啦
        wct.reorder(mRootTaskInfo.token, false /* onTop */);
        mTaskOrganizer.applyTransaction(wct);
        mSyncQueue.runInSync(t -> {
    
    
            setResizingSplits(false /* resizing */);
            t.setWindowCrop(mMainStage.mRootLeash, null)
                    .setWindowCrop(mSideStage.mRootLeash, null);
            setDividerVisibility(false, t);
        });
//省略
    }

対応する mSideStage.removeAllTask​​s メソッドを見てください。

   boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
    
    
        if (mChildrenTaskInfo.size() == 0) return false;
        wct.reparentTasks(
                mRootTaskInfo.token,
                null /* newParent */,
                CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
                CONTROLLED_ACTIVITY_TYPES,
                toTop);
        return true;
    }


reparentTasks と呼ばれる、reparentTasks Frameworks/base/core/java/android/window/WindowContainerTransaction.javaを見てみましょう。

public WindowContainerTransaction reparentTasks(@Nullable WindowContainerToken currentParent,
            @Nullable WindowContainerToken newParent, @Nullable int[] windowingModes,
            @Nullable int[] activityTypes, boolean onTop, boolean reparentTopOnly) {
    
    
        mHierarchyOps.add(HierarchyOp.createForChildrenTasksReparent(
                currentParent != null ? currentParent.asBinder() : null,
                newParent != null ? newParent.asBinder() : null,
                windowingModes,
                activityTypes,
                onTop,
                reparentTopOnly));
        return this;
    }

//创建对应HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT的HierarchyOp
        public static HierarchyOp createForChildrenTasksReparent(IBinder currentParent,
                IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop,
                boolean reparentTopOnly) {
    
    
            return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT)
                    .setContainer(currentParent)
                    .setReparentContainer(newParent)
                    .setWindowingModes(windowingModes)
                    .setActivityTypes(activityTypes)
                    .setToTop(onTop)
                    .setReparentTopOnly(reparentTopOnly)
                    .build();
        }

この時点で、systemui 部分の終了操作が完了します。

システムサーバー側の呼び出しを確認してください。

Frameworks/base/services/core/java/com/android/server/wm/WindowOrganizerController.java

 private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
            int syncId, @Nullable Transition transition, boolean isInLockTaskMode,
            @NonNull CallerInfo caller, @Nullable IBinder errorCallbackToken,
            @Nullable ITaskFragmentOrganizer organizer, @Nullable Transition finishTransition) {
    
    
            //省略
               switch (type) {
    
    
            case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: {
    
    
            //核心方法
                effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId);
                break;
            }
            //省略
            }   

コアメソッド reparentChildrenTasksHierarchyOp がここで呼び出されます


 private int reparentChildrenTasksHierarchyOp(WindowContainerTransaction.HierarchyOp hop,
            @Nullable Transition transition, int syncId) {
    
    
        WindowContainer<?> currentParent = hop.getContainer() != null
                ? WindowContainer.fromBinder(hop.getContainer()) : null;
        WindowContainer newParent = hop.getNewParent() != null
                ? WindowContainer.fromBinder(hop.getNewParent()) : null;
        if (currentParent == null && newParent == null) {
    
    
           //省略
        } else if (newParent == null) {
    
    //这里传递为null,所以给予没人的parent为DefaultTaskDisplayArea
            newParent = currentParent.asTask().getDisplayContent().getDefaultTaskDisplayArea();
        }

       //省略
        final ArrayList<Task> tasksToReparent = new ArrayList<>();
//对当前的task节点下面所有children进行遍历
        currentParent.forAllTasks(task -> {
    
    
            final boolean reparent;
            //注意这里的话可能activitytype和windowmode不支持,就要直接返回不会放入tasksToReparent
            if (!ArrayUtils.contains(hop.getActivityTypes(), task.getActivityType())
                    || !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) {
    
    
                return false;
            }
					//如果放到顶部的就放到
            if (hop.getToTop()) {
    
    
                tasksToReparent.add(0, task);
            } else {
    
    
                tasksToReparent.add(task);
            }
            return hop.getReparentTopOnly() && tasksToReparent.size() == 1;
        });

        final int count = tasksToReparent.size();
        for (int i = 0; i < count; ++i) {
    
    
            final Task task = tasksToReparent.get(i);
          //省略
          //刚好这里newParent就是TaskDisplayArea,即直接把原理挂在上下分屏的task挂到TaskDisplayArea下面
            if (newParent instanceof TaskDisplayArea) {
    
    
                // For now, reparenting to display area is different from other reparents...
                task.reparent((TaskDisplayArea) newParent, hop.getToTop());
            } else {
    
    
                task.reparent((Task) newParent,
                        hop.getToTop() ? POSITION_TOP : POSITION_BOTTOM,
                        false /*moveParents*/, "processChildrenTaskReparentHierarchyOp");
            }
        }
        return TRANSACT_EFFECTS_LIFECYCLE;
    }

このようにして、分割画面全体が終了し、コアプロセスが完了します。ライフサイクルの変更をトリガーするには、残りをresumeToActivityとensureVisibleActivityに関連付ける必要があります。

該当分割線の該当位置の初期化処理を補足します 位置は上、下、中、上半分、下半分の合計5箇所あります 作成処理は以下の通りです

07-15 16:51:55.253   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:301)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.253   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 810
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:474)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.maybeAddTarget(DividerSnapAlgorithm.java:362)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addNonDismissingTargets(DividerSnapAlgorithm.java:323)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addRatio16_9Targets(DividerSnapAlgorithm.java:353)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:305)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 1463
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:474)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addMiddleTarget(DividerSnapAlgorithm.java:369)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addNonDismissingTargets(DividerSnapAlgorithm.java:324)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addRatio16_9Targets(DividerSnapAlgorithm.java:353)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:305)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 2115
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:474)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.maybeAddTarget(DividerSnapAlgorithm.java:362)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addNonDismissingTargets(DividerSnapAlgorithm.java:325)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addRatio16_9Targets(DividerSnapAlgorithm.java:353)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:305)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 2960
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:317)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

4. 分割画面終了部分

4.1 戻ると出る

applyExitSplitScreen:735, StageCoordinator (com.android.wm.shell.splitscreen)
exitSplitScreen:730, StageCoordinator (com.android.wm.shell.splitscreen)
onStageHasChildrenChanged:1187, StageCoordinator (com.android.wm.shell.splitscreen)
-$$Nest$monStageHasChildrenChanged:-1, StageCoordinator (com.android.wm.shell.splitscreen)
onStatusChanged:1864, StageCoordinator$StageListenerImpl (com.android.wm.shell.splitscreen)
sendStatusChanged:377, StageTaskListener (com.android.wm.shell.splitscreen)
onTaskVanished:276, StageTaskListener (com.android.wm.shell.splitscreen)
updateTaskListenerIfNeeded:552, ShellTaskOrganizer (com.android.wm.shell)
onTaskInfoChanged:465, ShellTaskOrganizer (com.android.wm.shell)
lambda$onTaskInfoChanged$6$android-window-TaskOrganizer$1:316, TaskOrganizer$1 (android.window)
run:-1, TaskOrganizer$1$$ExternalSyntheticLambda3 (android.window)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7898, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

4.2 全画面アクティビティの開始と終了


applyExitSplitScreen:735, StageCoordinator (com.android.wm.shell.splitscreen)
exitSplitScreen:730, StageCoordinator (com.android.wm.shell.splitscreen)
onStageVisibilityChanged:1079, StageCoordinator (com.android.wm.shell.splitscreen)
-$$Nest$monStageVisibilityChanged:-1, StageCoordinator (com.android.wm.shell.splitscreen)
onStatusChanged:1868, StageCoordinator$StageListenerImpl (com.android.wm.shell.splitscreen)
sendStatusChanged:377, StageTaskListener (com.android.wm.shell.splitscreen)
onTaskInfoChanged:251, StageTaskListener (com.android.wm.shell.splitscreen)
onTaskInfoChanged:468, ShellTaskOrganizer (com.android.wm.shell)
lambda$onTaskInfoChanged$6$android-window-TaskOrganizer$1:316, TaskOrganizer$1 (android.window)
run:-1, TaskOrganizer$1$$ExternalSyntheticLambda3 (android.window)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7898, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

4.3 ドラッグ アンド ドロップで正常に終了する

applyExitSplitScreen:735, StageCoordinator (com.android.wm.shell.splitscreen)
exitSplitScreen:730, StageCoordinator (com.android.wm.shell.splitscreen)
onSnappedToDismiss:1219, StageCoordinator (com.android.wm.shell.splitscreen)
lambda$snapToTarget$0:400, SplitLayout (com.android.wm.shell.common.split)
$r8$lambda$eePA67tW_LBGfBgW6IWST62hoPI:-1, SplitLayout (com.android.wm.shell.common.split)
run:-1, SplitLayout$$ExternalSyntheticLambda0 (com.android.wm.shell.common.split)
onAnimationEnd:458, SplitLayout$1 (com.android.wm.shell.common.split)
:-1, Animator$AnimatorListener (android.animation)
endAnimation:1333, ValueAnimator (android.animation)
doAnimationFrame:1575, ValueAnimator (android.animation)
doAnimationFrame:307, AnimationHandler (android.animation)
-$$Nest$mdoAnimationFrame:-1, AnimationHandler (android.animation)
doFrame:86, AnimationHandler$1 (android.animation)
run:1229, Choreographer$CallbackRecord (android.view)
run:1239, Choreographer$CallbackRecord (android.view)
doCallbacks:899, Choreographer (android.view)
doFrame:827, Choreographer (android.view)
run:1214, Choreographer$FrameDisplayEventReceiver (android.view)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7898, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

おすすめ

転載: blog.csdn.net/learnframework/article/details/131082401