Android 12 S activity切换动画介绍

22 篇文章 6 订阅
17 篇文章 1 订阅

系列文章

Android 12 S WindowManager Transition动画介绍

Android 12 S ActivityManager解读之从dumpsys activity activities看activity

Android 12 S WindowManager解读之从dumpsys window windows看window

Android 12 S WindowInset解析

 

5566fcdeb44343569c458a77fcb47658.jpg

 

 

在activity启动过程中, activity切换动画的意思是两个activity之间进行的切换动画,指前一个activity从resume状态切换到paused状态,新起的acticity将从start切换到resume状态,在AppTransitionController#getTransitCompatType中可知TRANSIT_OLD_ACTIVITY_OPEN是由TRANSIT_OPEN转化而来,而dc.prepareAppTransition(TRANSIT_OPEN)会在两个地方被调用,一个是startActivityLocked,另一个是resumeTopActivityInnerLocked,但这个resumeTopActivityInnerLocked方法在启动过程中会被调用两次,第一次调用时是在startActivityInner过程中调用的,此时前一个activity并未进入paused状态,第二次则是前一个activity进入paused状态了,然后回掉completePausedLocked,继而调用了此方法,如上图。

static @TransitionOldType int getTransitCompatType(

                                AppTransition appTransition,
                                        ArraySet<ActivityRecord> openingApps,

                                                ArraySet<ActivityRecord> closingApps, 

                                                         @Nullable WindowState wallpaperTarget,

                                                                @Nullable WindowState oldWallpaper,

                                                                        boolean skipAppTransitionAnimation) {

...

//appTransition.mNextAppTransitionRequests如果包含TRANSIT_OPEN
        if (appTransition.containsTransitRequest(TRANSIT_OPEN)) {
            if (isTaskOpening) {
                return (appTransition.getTransitFlags() & TRANSIT_FLAG_OPEN_BEHIND) != 0  ? TRANSIT_OLD_TASK_OPEN_BEHIND : TRANSIT_OLD_TASK_OPEN;
            }
            if (isActivityOpening) {
                return TRANSIT_OLD_ACTIVITY_OPEN;
            }
        }
...

}

 

void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity,

            boolean newTask, boolean keepCurTransition, ActivityOptions options,

            @Nullable ActivityRecord sourceRecord) {

...

        // Place a new activity at top of root task, so it is next to interact with the user.

 

        //将新activity放在根任务的顶部,以便它接下来与用户交互。

 

        // If we are not placing the new activity frontmost, we do not want to deliver the onUserLeaving callback to the actual frontmost activity

 

        //如果我们没有将新activity放在最前面,我们不希望将 onUserLeave 回调传递到实际的最前面的activity

        final Task activityTask = r.getTask();

        if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) {

            mTaskSupervisor.mUserLeaving = false;

            if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,

                    "startActivity() behind front, mUserLeaving=false");

        }

 

        task = activityTask;

 

        // Slot the activity into the history root task and proceed

        ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to task %s "

                        + "callers: %s", r, task, new RuntimeException("here").fillInStackTrace());

 

        //将此activity调整到task的top顶部

        task.positionChildAtTop(r);

 

        // The transition animation and starting window are not needed if {@code allowMoveToFront} is false, because the activity won't be visible.

 

       //如果allowMoveToFront为false,则过渡动画和starting窗口就不需要了,因为这个activity不会设置为可见状态。1. 如果当前r不属于home或者recent task,或者当前是一个activity;  2.允许此r移动到最前端front。 以上1,2两个条件都满足的话,则进入此判断

        if ((!isHomeOrRecentsRootTask() || hasActivity()) && allowMoveToFront) {

            final DisplayContent dc = mDisplayContent;

            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,

                    "Prepare open transition: starting " + r);

            // TODO(shell-transitions): record NO_ANIMATION flag somewhere.

            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {

 

//如果r的flag中带有FLAG_ACTIVITY_NO_ANIMATION,则不会执行动画,此r也会被添加到mNoAnimActivities。

 

                dc.prepareAppTransition(TRANSIT_NONE);

                mTaskSupervisor.mNoAnimActivities.add(r);

            } else {

                int transit = TRANSIT_OLD_ACTIVITY_OPEN;

                if (newTask) {

                    if (r.mLaunchTaskBehind) {

                        transit = TRANSIT_OLD_TASK_OPEN_BEHIND;

                    } else {

                        // If a new task is being launched, then mark the existing top activity as supporting picture-in-picture while pausing only if the starting activity would not be considered an overlay on top of the current activity (eg. not fullscreen, or the assistant)

                        if (canEnterPipOnTaskSwitch(focusedTopActivity,

                                null /* toFrontTask */, r, options)) {

                            focusedTopActivity.supportsEnterPipOnTaskSwitch = true;

                        }

                        transit = TRANSIT_OLD_TASK_OPEN;

                    }

                }

 

//如果当前的r所在的task不是新的task,则会设置TRANSIT_OPEN,最终执行动画TRANSIT_OLD_ACTIVITY_OPEN。

                dc.prepareAppTransition(TRANSIT_OPEN);

                mTaskSupervisor.mNoAnimActivities.remove(r);

            }

...

 

    @GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) {
...
        boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
        if (mResumedActivity != null) {
            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity);

//第一次调用时,前一个activity还未paused,将会去执行pause操作。

            pausing |= startPausingLocked(false /* uiSleeping */, next,
                    "resumeTopActivityInnerLocked");

        }

        // We are starting up the next activity, so tell the window manager that the previous one will be hidden soon.  This way it can know to ignore it when computing the desired screen orientation.
        boolean anim = true;
        final DisplayContent dc = taskDisplayArea.mDisplayContent;

//第一次调用时prev不是null
        if (prev != null) {
            if (prev.finishing) {//如果前一个activity正在finishing
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare close transition: prev=" + prev);
                if (mTaskSupervisor.mNoAnimActivities.contains(prev)) {
                    anim = false;
                    dc.prepareAppTransition(TRANSIT_NONE);
                } else {
                    dc.prepareAppTransition(TRANSIT_CLOSE);
                }
                prev.setVisibility(false);
            } else {//如果前一个activity未在finishing
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare open transition: prev=" + prev);

                 //如果新起的activity没有动画
                if (mTaskSupervisor.mNoAnimActivities.contains(next)) {
                    anim = false;
                    dc.prepareAppTransition(TRANSIT_NONE);
                } else {

                  //prepare
                    dc.prepareAppTransition(TRANSIT_OPEN,
                            next.mLaunchTaskBehind ? TRANSIT_FLAG_OPEN_BEHIND : 0);
                }
            }
        } else {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
            if (mTaskSupervisor.mNoAnimActivities.contains(next)) {
                anim = false;
                dc.prepareAppTransition(TRANSIT_NONE);
            } else {

                dc.prepareAppTransition(TRANSIT_OPEN);
            }
        }

 

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值