【Android 13源码分析】应用启动动画-app_transition-1

2,144 阅读11分钟

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。

                        -- 服装学院的IT男

根据之前的分析,首先执行的是 2个 app_transtion 动画和一个壁纸的 window_animation 动画。 这3个动画几乎是同时执行和结束,不过用户视觉干啥最明显的其实还是应用启动的 app_transtion 动画,所以主要还是分析这个动画,在分析的过程中也会提及另外2个。

本篇为第一篇,主要介绍 launcher 点击图标后,launcher 是如何构建动画用到的相关类的。然后再结束了一些这些类的如何传递到 system_server 进程,并被解析保存的。

1. 流程分析

以前的 Android 手机桌面点击图标启动是没有动画的,但 iPhone 是有的,iPhone 的动画是点击图标,然后会有一个类似于从图标位置开始放大到全屏的效果,退出应用也有。这种视觉效果就非常好,

这个动画的是一个“远端动画” ,播放是在 launcher 进程执行的,而动画的操作的 Surface 是在 system_server 创建的,也就是 leash 图层。

所以这个过程必然涉及到进程通信 app_transtion 动画的一级框图如下:

一级框图-app_transiotion动画.png

    1. 用户在 launcher 点击图标后,开始触发流程,首先会构建 RemoteAnimationAdapter,AppLaunchAnimationRunner 这2个播放动画的关键类,这2个类会通过 ActivityOptions 传递到 system_server 进程

我们知道启动 Activity 的一些参数都是通过 ActivityOptions 方式传递到 system_server 进程的,然后在构建 ActivityRecord 的时候解析参数。

    1. system_server 进程在执行启动逻辑的过程中会创建动画需要的 leash 图层
    1. 再跨进程把 leash 图层传递到 launcher ,触发 launcher 执行动画。具体来说是会构建一个 RemoteAnimationTarget 数组,里面是会带上 leash 图层,然后再带上动画结束回调,再把这2个对象传递给 launcher 进程
    1. launcher 进程开始执行动画逻辑
    1. 动画结束后会触发由 system_server 进程传递过来的回调做收尾处理

2. launcher 处理

这块主要就是看 launcher 是如何创建 RemoteAnimationAdapter,AppLaunchAnimationRunner 等关键类的

launcher点击图标的时候会触发 Activity::startActivity 方法,在这个时候就会创建 RemoteAnimationAdapter

Activity启动流程执行Activity启动的前面应用端的调用链如下:

Activity::startActivity
    Activity::startActivity
        Activity::startActivityForResult
            Instrumentation::execStartActivity
                ActivityTaskManagerService::startActivity

在这前面其实还有 ActivityOptions 的构建与一些参数拼接的逻辑,比如当前分析动画逻辑的 RemoteAnimationAdapter 的构建就需要看一下这部分的调用链

桌面点击也是执行View的onClick方法,在launcher中图标的点击事件交给了ItemClickHandler处理,这部分调用链如下:

09-24 21:30:11.447 16447 16447 D biubiubiu: RemoteAnimationAdapter  init: com.android.systemui.shared.system.RemoteAnimationAdapterCompat$1@8981e38
09-24 21:30:11.447 16447 16447 D biubiubiu: java.lang.Exception
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at android.view.RemoteAnimationAdapter.<init>(RemoteAnimationAdapter.java:76)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at android.view.RemoteAnimationAdapter.<init>(RemoteAnimationAdapter.java:86)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.systemui.shared.system.RemoteAnimationAdapterCompat.<init>(RemoteAnimationAdapterCompat.java:56)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.QuickstepTransitionManager.getActivityLaunchOptions(QuickstepTransitionManager.java:299)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.BaseQuickstepLauncher.getActivityLaunchOptions(BaseQuickstepLauncher.java:549)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.views.AppLauncher.startActivitySafely(AppLauncher.java:74)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.Launcher.startActivitySafely(Launcher.java:2133)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.uioverrides.QuickstepLauncher.startActivitySafely(QuickstepLauncher.java:178)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.touch.ItemClickHandler.startAppShortcutOrInfoActivity(ItemClickHandler.java:381)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.touch.ItemClickHandler.onClickAppShortcut(ItemClickHandler.java:304)
09-24 21:30:11.447 16447 16447 D biubiubiu: 	at com.android.launcher3.touch.ItemClickHandler.onClick(ItemClickHandler.java:97)

最终整理出的调用链如下:

ItemClickHandler::onClick
    ItemClickHandler::onClickAppShortcut
        ItemClickHandler::startAppShortcutOrInfoActivity
            QuickstepLauncher::startActivitySafely
                Launcher::startActivitySafely
                    AppLauncher::startActivitySafely
                        BaseQuickstepLauncher::getActivityLaunchOptions    ---构建 RemoteAnimationAdapter 等参数
                            QuickstepTransitionManager::getActivityLaunchOptions -- 构建 AppLaunchAnimationRunner
                                AppLaunchAnimationRunner::init
                                LauncherAnimationRunner::init
                                RemoteAnimationAdapterCompat::init
                                    RemoteAnimationAdapter::init
                                ActivityOptionsCompat::makeRemoteAnimation
                                    ActivityOptions::makeRemoteAnimation  --将RemoteAnimationAdapter包装在ActivityOptions中
                                ActivityOptionsWrapper::init
                        Activity::startActivity  -- Activity流程
                            Activity::startActivity
                                Activity::startActivity
                                    Activity::startActivityForResult
                                        Instrumentation::execStartActivity
                                            ActivityTaskManagerService::startActivity

下面主要关心创建 RemoteAnimationAdapter 的流程

# AppLauncher
    default boolean startActivitySafely(
            View v, Intent intent, @Nullable ItemInfo item) {
                ......
                Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
                ......
                context.startActivity(intent, optsBundle);
                ......
            }

这部分代码也会最终触发 Activity::startActivity 现在主要关心的是参数 LaunchOptions 的创建,也就是 getActivityLaunchOptions 方法,这个调用的是子类 BaseQuickstepLauncher 重写的方法

# BaseQuickstepLauncher

    private QuickstepTransitionManager mAppTransitionManager;

    default ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
            ActivityOptionsWrapper activityOptions = mAppTransitionManager.hasSimpleAnimationTransition()
                ? mAppTransitionManager.getActivityLaunchOptions(v): super.getActivityLaunchOptions(v, item);
            ......
    }

注意,下面会创建 AppLaunchAnimationRunner

# QuickstepTransitionManager

    public ActivityOptionsWrapper getActivityLaunchOptions(View v) {
        ......
        // 重点* 1.  创建AppLaunchAnimationRunner
        mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback);
        // 重点* 2.  创建LauncherAnimationRunner
        RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(
                mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */);
        // 动画时长
        long duration = fromRecents
                ? RECENTS_LAUNCH_DURATION
                : APP_LAUNCH_DURATION;
        long statusBarTransitionDelay = duration - STATUS_BAR_TRANSITION_DURATION
                - STATUS_BAR_TRANSITION_PRE_DELAY;
        // 重点* 3. 创建RemoteAnimationAdapterCompat,将LauncherAnimationRunner对象传递
        RemoteAnimationAdapterCompat adapterCompat =
                new RemoteAnimationAdapterCompat(runner, duration, statusBarTransitionDelay,
                        mLauncher.getIApplicationThread());
        // 重点* 4. 最终包装成一个ActivityOptionsWrapper对象返回,ActivityOptionsCompat.makeRemoteAnimation返回的是一个ActivityOptions
        return new ActivityOptionsWrapper(
                ActivityOptionsCompat.makeRemoteAnimation(adapterCompat), onEndCallback);
        ......
    }

重点分析: 这里一个创建了4个对象,其中有2个比较容易混淆的对象 AppLaunchAnimationRunner 和 LauncherAnimationRunner 需要留意。

    1. 创建 AppLaunchAnimationRunner 对象,这个类是实现类 RemoteAnimationFactory 接口,所以也实现了其 onCreateAnimation 方法最后也是在这个类里真正的开始动画的
    1. 创建 LauncherAnimationRunner 对象,将 AppLaunchAnimationRunner 对象作为其构造参数
    1. 创建 RemoteAnimationAdapterCompat 对象,又将 LauncherAnimationRunner 作为其构造参数,内部会创建 RemoteAnimationAdapter
    1. 创建 ActivityOptionsWrapper 对象作为返回,adapterCompat 又作为其构造参数,这个是 ActivityOptions 的包装类,会传递到 system_server 进程,这样这边的几个对象都会一起传递过去了。

这边将 RemoteAnimationAdapterCompat 传递了出去,但是根据这几个变量构建的关系,可以知道只要拿到了 RemoteAnimationAdapterCompat 对象就能调用到其他3个对象。

下面对这4个对象详细解释

2.1 AppLaunchAnimationRunner 动画最终执行的地方

# QuickstepTransitionManager

    private class AppLaunchAnimationRunner implements RemoteAnimationFactory {

        @Override
        public void onCreateAnimation(int transit,
                RemoteAnimationTargetCompat[] appTargets,
                RemoteAnimationTargetCompat[] wallpaperTargets,
                RemoteAnimationTargetCompat[] nonAppTargets,
                LauncherAnimationRunner.AnimationResult result) {
                    ......
                    // 动画执行逻辑
                    composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
                        launcherClosing);
                    ......
                }
    }
// 这里需要看看个接口,因为 AppLaunchAnimationRunner 实现类这个接口。这个接口主要有个方法就是 onCreateAnimation
# LauncherAnimationRunner

    public interface RemoteAnimationFactory {

        /**
         * Called on the UI thread when the animation targets are received. The implementation must
         * call {@link AnimationResult#setAnimation} with the target animation to be run.
         */
        void onCreateAnimation(int transit,
                RemoteAnimationTargetCompat[] appTargets,
                RemoteAnimationTargetCompat[] wallpaperTargets,
                RemoteAnimationTargetCompat[] nonAppTargets,
                LauncherAnimationRunner.AnimationResult result);

        /**
         * Called when the animation is cancelled. This can happen with or without
         * the create being called.
         */
        default void onAnimationCancelled() { }
    }

具体的 onCreateAnimation 后面介绍动画执行的时候会详细看,目前需要知道AppLaunchAnimationRunner 实现了 RemoteAnimationFactory接口,后续会调用其 onCreateAnimation 方法触发开始动画。

2.2 LauncherAnimationRunner

# LauncherAnimationRunner

    public class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
        // 当前场景是将 AppLaunchAnimationRunner 作为弱引用
        private final WeakReference<RemoteAnimationFactory> mFactory;

        public LauncherAnimationRunner(Handler handler, RemoteAnimationFactory factory,
                boolean startAtFrontOfQueue) {  
            mHandler = handler;
            // 当前场景构建这个传递的是AppLaunchAnimationRunner
            mFactory = new WeakReference<>(factory);
            mStartAtFrontOfQueue = startAtFrontOfQueue;
        }

        // 获取
        private RemoteAnimationFactory getFactory() {
            RemoteAnimationFactory factory = mFactory.get();
            return factory != null ? factory : DEFAULT_FACTORY;
        }
    }

这里需要注意,mFactory 的类型既然泛型是接口,说明不仅仅当前一种场景,不过目前的分析还是以 AppLaunchAnimationRunner 作为起类型看就可以了。 后续动画执行的时候,需要还需要通过这个类来调用 AppLaunchAnimationRunner::onCreateAnimation ,那么根据目前贴上的代码肯定是通过 LauncherAnimationRunner::getFactory 来获取AppLaunchAnimationRunner 对象的

2.3 RemoteAnimationAdapterCompat 核心是内部的RemoteAnimationAdapter

# RemoteAnimationAdapterCompat
    // 关键成员是RemoteAnimationAdapter对象
    private final RemoteAnimationAdapter mWrapped;

    public RemoteAnimationAdapterCompat(RemoteAnimationRunnerCompat runner, long duration,
            long statusBarTransitionDelay, IApplicationThread appThread) {
        // 通过wrapRemoteAnimationRunner方法将传进来的LauncherAnimationRunne对象包装
        mWrapped = new RemoteAnimationAdapter(wrapRemoteAnimationRunner(runner), duration,
                statusBarTransitionDelay);
        mRemoteTransition = buildRemoteTransition(runner, appThread);
    }

    // 返回一个binder对象,用于跨进程通信
    public static IRemoteAnimationRunner.Stub wrapRemoteAnimationRunner(
            final RemoteAnimationRunnerCompat remoteAnimationAdapter) {
        return new IRemoteAnimationRunner.Stub() {
            @Override
            public void onAnimationStart(@TransitionOldType int transit,
                    RemoteAnimationTarget[] apps,
                    RemoteAnimationTarget[] wallpapers,
                    RemoteAnimationTarget[] nonApps,
                    final IRemoteAnimationFinishedCallback finishedCallback) {
                // 这3个RemoteAnimationTargetCompat数组,里面的成员是实际要参与动画的目标对象(Target)
                // system_server 进程跨进程调用的时候会传递具体要做动画目标对象过来
                final RemoteAnimationTargetCompat[] appsCompat =
                        RemoteAnimationTargetCompat.wrap(apps);
                final RemoteAnimationTargetCompat[] wallpapersCompat =
                        RemoteAnimationTargetCompat.wrap(wallpapers);
                final RemoteAnimationTargetCompat[] nonAppsCompat =
                        RemoteAnimationTargetCompat.wrap(nonApps);
                // 定义个动画结束的回调,也就是执行参数finishedCallback的onAnimationFinished回调
                final Runnable animationFinishedCallback = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            finishedCallback.onAnimationFinished();
                        } catch (RemoteException e) {
                            Log.e("ActivityOptionsCompat", "Failed to call app controlled animation"
                                    + " finished callback", e);
                        }
                    }
                };
                // 实际上是调用LauncherAnimationRunner的onAnimationStart
                remoteAnimationAdapter.onAnimationStart(transit, appsCompat, wallpapersCompat,
                        nonAppsCompat, animationFinishedCallback);
            }

            @Override
            public void onAnimationCancelled(boolean isKeyguardOccluded) {
                // 实际上是调用LauncherAnimationRunner的onAnimationCancelled
                remoteAnimationAdapter.onAnimationCancelled();
            }
        };
    }

这里的代码都是非常重要的,关键的注释也加在了代码上。这边有跨进程调用的关键方法,是通过 wrapRemoteAnimationRunner 方法将返回的binder对象,这个对象作为 RemoteAnimationAdapter 的构造参数,所以还是要看看 RemoteAnimationAdapter 的构造方法

# RemoteAnimationAdapter
    public RemoteAnimationAdapter(IRemoteAnimationRunner runner, long duration,
            long statusBarTransitionDelay, boolean changeNeedsSnapshot) {
        //  将跨进程通信的runner保存到mRunner中
        mRunner = runner;
        // 时长
        mDuration = duration;
        mChangeNeedsSnapshot = changeNeedsSnapshot;
        mStatusBarTransitionDelay = statusBarTransitionDelay;
    }

目前可以知道RemoteAnimationAdapterCompat 其实只是个包装类,真正干活的是内部的 RemoteAnimationAdapter 。 而 RemoteAnimationAdapter 下的成员变量 mRunner 是个 binder 对象看着就是最终是用来跨进程通信的。

而这个 mRunner 真正做事还是要靠 LauncherAnimationRunner RemoteAnimationAdapter 作为 RemoteAnimationAdapterCompat 下 的 mWrapped 对象

2.4 ActivityOptionsWrapper

# ActivityOptionsWrapper

    public final ActivityOptions options;
    public final RunnableList onEndCallback;

    public ActivityOptionsWrapper(ActivityOptions options, RunnableList onEndCallback) {
        this.options = options;
        this.onEndCallback = onEndCallback;
    }

ActivityOptionsWrapper这个对象就比较简单,作用也和类名一样是 ActivityOptions 的包装类,那么根据构成方法的第一个参数就可以知道 ActivityOptionsCompat::makeRemoteAnimation 放回的肯定是 ActivityOptions 对象了。

# ActivityOptionsCompat
    public static ActivityOptions makeRemoteAnimation(
            RemoteAnimationAdapterCompat remoteAnimationAdapter) {
        // getWrapped就是RemoteAnimationAdapter对象
        return ActivityOptions.makeRemoteAnimation(remoteAnimationAdapter.getWrapped(),
                remoteAnimationAdapter.getRemoteTransition().getTransition());
    }

# ActivityOptions
    @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
    public static ActivityOptions makeRemoteAnimation(RemoteAnimationAdapter remoteAnimationAdapter,
            RemoteTransition remoteTransition) {
        final ActivityOptions opts = new ActivityOptions();
        // 将刚创建的RemoteAnimationAdapter放到ActivityOptions中
        opts.mRemoteAnimationAdapter = remoteAnimationAdapter;
        // 注意这个type
        opts.mAnimationType = ANIM_REMOTE_ANIMATION;
        // 赋值remoteTransition
        opts.mRemoteTransition = remoteTransition;
        return opts;
    }

这边发现创建 ActivityOptions 的时候传递的是 RemoteAnimationAdapterCompat 下的 mWrapped 对象,那也就是说ActivityOptions 下的 mRemoteAnimationAdapter 其实就是RemoteAnimationAdapter

2.5 几个类的关系小结

上面涉及到的类比较关系,关系也是一级套一级,最终由ActivityOptions带着RemoteAnimationAdapter传递到了 system_server 进程,既然传过去了,后续肯定是要调用回来的,所以这几类的关系需要清晰,否则后续调用就会很迷糊,这边将这几个类的关系整理了2种类型的图,作为后续翻阅的参考。

launcher构建的几个类的包含关系.png

类的简单关系如下:

launcher构建的几个类的UML.png

3. system_server 进程解析获取 RemoteAnimationAdapter

Activity启动流程中我们知道在 system_server 进程,会创建 ActivityRecord 对象,前面提到的 ActivityOptions 在这个时候被解析。 做了很多事,其中最重要的就是把 launcher 构建的动画 RemoteAnimationAdapter 保存起来,等实际到了再触发动画的执行。

# ActivityRecord 

    private RemoteAnimationAdapter mPendingRemoteAnimation;

    private void setOptions(@NonNull ActivityOptions options) {
        mLaunchedFromBubble = options.getLaunchedFromBubble();
        mPendingOptions = options;
        // 前面看到是这个type
        if (options.getAnimationType() == ANIM_REMOTE_ANIMATION) {
            // 重点* 赋值
            mPendingRemoteAnimation = options.getRemoteAnimationAdapter();
        }
        mPendingRemoteTransition = options.getRemoteTransition();
    }

**那么 ActivityRecord 中就持有了 launcher 传递过来的 RemoteAnimationAdapter 对象,这点很重要。**然后看看将值解析出来后,是什么时候使用的。

在Activity启动流程中, ActivityRecord 创建后,后面会触发 TargetActivity 的pause,就会执行下面这个调用链:

ActivityClientController::activityPaused
    ActivityRecord::activityPaused
        TaskFragment::completePause
            RootWindowContainer::resumeFocusedTasksTopActivities      
                RootWindowContainer::resumeFocusedTasksTopActivities
                    Task::resumeTopActivityUncheckedLocked
                        Task::resumeTopActivityInnerLocked
                            TaskFragment::resumeTopActivity
                                ActivityTaskSupervisor::startSpecificActivity  -- 尝试启动 Activity

在 TaskFragment::resumeTopActivity 方法看到会调用 ActivityTaskSupervisor::startSpecificActivity ,如果进程未启动则会触发创建进程。不过当前分析的的动画相关的流程

# TaskFragment
    final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        ......
        // 处理activity的pause流程
        boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
        ......
        // 默认需要动画
        boolean anim = true;
            ......
                if (mTaskSupervisor.mNoAnimActivities.contains(next)) {
                    anim = false;
                    dc.prepareAppTransition(TRANSIT_NONE);
                } else {
                    // 重点* 1. 触发AppTransition::prepareAppTransition
                    dc.prepareAppTransition(TRANSIT_OPEN,
                            next.mLaunchTaskBehind ? TRANSIT_FLAG_OPEN_BEHIND : 0);
                }
            ......

        if (anim) {
            // 重点* 2. 当前场景 anim为true,这里使用launcher带了的adapter构建RemoteAnimationController
            next.applyOptionsAnimation();
        } else {
            next.abortAndClearOptionsAnimation();
        }
        ......
        // 重点* 3.  启动 Activity 流程
        mTaskSupervisor.startSpecificActivity(next, true, true);
    }

这里有3个重点:

    1. 执行 DisplayContent::prepareAppTransition 表示准备了一个打开应用的转换事件
    1. ActivityRecord::applyOptionsAnimation 后面会把 launcher 传递过来的动画 adapter 保存 RemoteAnimationController 下。
    1. 启动 Activity 流程

DisplayContent::prepareAppTransition 下一篇再看,进程的创建流程之前也介绍过,当前主要关心动画 RemoteAnimationAdapter 是怎么保存的,所以上面这块代码主要看 applyOptionsAnimation 这一段分析即可。

# ActivityRecord

    void applyOptionsAnimation() {
        if (DEBUG_TRANSITION) Slog.i(TAG, "Applying options for " + this);
       
        if (mPendingRemoteAnimation != null) {
            // 只看这里
            mDisplayContent.mAppTransition.overridePendingAppTransitionRemote(
                    mPendingRemoteAnimation);
        } else ......
    }

之前看ActivityRecord::setOptions方法的时候就知道 mPendingRemoteAnimation 已经有值了,就是 launcher 传递过来的。

# AppTransition
    private RemoteAnimationController mRemoteAnimationController;

    void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
        // 重点* 注意这里的第一个参数为 remoteAnimationAdapter, 第二个参数为false
        overridePendingAppTransitionRemote(remoteAnimationAdapter, false /* sync */);
    }

    // mRemoteAnimationController被赋值的地方
    void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter,
            boolean sync) {
        // 打印log,需要注意下打印的输出
        ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s",
                        isTransitionSet(), remoteAnimationAdapter);
                        
        // 前面说会执行 DisplayContent::prepareAppTransition,执行完这个条件满足了
        if (isTransitionSet() && !mNextAppTransitionIsSync) {
            clear();
            mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
            // 重点* 构造RemoteAnimationController,最终这里会触发远端动画的执行,注意第三个删除
            mRemoteAnimationController = new RemoteAnimationController(mService, mDisplayContent,
                    remoteAnimationAdapter, mHandler);
            mNextAppTransitionIsSync = sync;
        }
    }

这里可以看到 launcher 传递过来的 RemoteAnimationAdapter 是被拿来构建 RemoteAnimationController 对象了。

# RemoteAnimationController
    // 这个是launcher传递过来的
    private final RemoteAnimationAdapter mRemoteAnimationAdapter;

    RemoteAnimationController(WindowManagerService service, DisplayContent displayContent,
            RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) {
        mService = service;
        mDisplayContent = displayContent;
        mRemoteAnimationAdapter = remoteAnimationAdapter;
        mHandler = handler;
    }

目前已经知道,launcher 传递过来的 RemoteAnimationAdapter 被赋值到了 RemoteAnimationController 下的 mRemoteAnimationController 中,后面要开始动画的时候肯定会使用到这个对象

整理后较为完整的调用链如下:

ActivityClientController::activityPaused
    ActivityRecord::activityPaused
        TaskFragment::completePause
            RootWindowContainer::resumeFocusedTasksTopActivities      
                RootWindowContainer::resumeFocusedTasksTopActivities
                    Task::resumeTopActivityUncheckedLocked
                        Task::resumeTopActivityInnerLocked
                            TaskFragment::resumeTopActivity
                                DisplayContent::prepareAppTransition
                                    AppTransition::prepareAppTransition   -- 将TRANSIT_OPEN这个transit添加进mNextAppTransitionRequests
                                ActivityRecord::applyOptionsAnimation
                                    AppTransition::overridePendingAppTransitionRemote
                                        AppTransition::overridePendingAppTransitionRemote -- 对mRemoteAnimationController赋值
                                            RemoteAnimationController::init     -- 远端动画的adapter保存在这
                                ActivityTaskSupervisor::startSpecificActivity   -- 尝试启动 Activity