忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。
-- 服装学院的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 动画的一级框图如下:
-
- 用户在 launcher 点击图标后,开始触发流程,首先会构建 RemoteAnimationAdapter,AppLaunchAnimationRunner 这2个播放动画的关键类,这2个类会通过 ActivityOptions 传递到 system_server 进程
我们知道启动 Activity 的一些参数都是通过 ActivityOptions 方式传递到 system_server 进程的,然后在构建 ActivityRecord 的时候解析参数。
-
- system_server 进程在执行启动逻辑的过程中会创建动画需要的 leash 图层
-
- 再跨进程把 leash 图层传递到 launcher ,触发 launcher 执行动画。具体来说是会构建一个 RemoteAnimationTarget 数组,里面是会带上 leash 图层,然后再带上动画结束回调,再把这2个对象传递给 launcher 进程
-
- launcher 进程开始执行动画逻辑
-
- 动画结束后会触发由 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 需要留意。
-
- 创建 AppLaunchAnimationRunner 对象,这个类是实现类 RemoteAnimationFactory 接口,所以也实现了其 onCreateAnimation 方法最后也是在这个类里真正的开始动画的
-
- 创建 LauncherAnimationRunner 对象,将 AppLaunchAnimationRunner 对象作为其构造参数
-
- 创建 RemoteAnimationAdapterCompat 对象,又将 LauncherAnimationRunner 作为其构造参数,内部会创建 RemoteAnimationAdapter
-
- 创建 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种类型的图,作为后续翻阅的参考。
类的简单关系如下:
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个重点:
-
- 执行 DisplayContent::prepareAppTransition 表示准备了一个打开应用的转换事件
-
- ActivityRecord::applyOptionsAnimation 后面会把 launcher 传递过来的动画 adapter 保存 RemoteAnimationController 下。
-
- 启动 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