重要类介绍
Animation
Animation定义在frameworks/base/core/java/android/view/animation/Animation.java,其子类有TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation等。
在给定了初始状态、结束状态、启动时间与持续时间后,该类可以为使用者计算其动画目标在任意时刻的变换(Transformation),这是Animation类唯一的用途。
Transformation类定义在frameworks/base/core/java/android/view/animation/Transformation.java,其描述了一个变换。它包含了两个分量:透明度及一个二维变换矩阵。同变换矩阵的运算一样,多个 Transformation 也可以进行类似于矩阵的先乘、后乘等叠加操作。其计算方法为:透明度分量相乘,变换矩阵分量进行相应的先乘、后乘。
Animation的getTransformation方法根据给定的时间戳,计算动画目标所需要进行的变换 。另外,其返回值如果为 true,则表示动画尚未完结,调用者需要继续处理下一帧动画。
Animation的子类可以重写applyTransformation方法实现自己的变换方法。
Animator
Animator定义在frameworks/base/core/java/android/animation/Animator.java,提供开始动画、结束动画方法,并且可以注册动画回调。
其子类frameworks/base/core/java/android/animation/ValueAnimator.java的使用示例如下:
val va = ValueAnimator.ofFloat(0f, 1f)
va.duration = 1000
va.addUpdateListener { Log.e("ValueAnimator", va.animatedValue.toString()) }
va.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) {
Log.e("ValueAnimator", "onAnimationStart")
}
override fun onAnimationEnd(animation: Animator?) {
Log.e("ValueAnimator", "onAnimationEnd")
}
})
va.start()
WindowAnimator
WindowAnimator定义在frameworks/base/services/core/java/com/android/server/wm/WindowAnimator.java。
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java有一个类型为WindowAnimator的成员变量mAnimator。
WindowManagerService的scheduleAnimationLocked方法:
/** Note that Locked in this case is on mLayoutToAnim */
void scheduleAnimationLocked() {
if (mAnimator != null) {
mAnimator.scheduleAnimation();
}
}
调用了WindowAnimator的scheduleAnimation方法:
void scheduleAnimation() {
if (!mAnimationFrameCallbackScheduled) {
mAnimationFrameCallbackScheduled = true;
mChoreographer.postFrameCallback(mAnimationFrameCallback);
}
}
这里的mAnimationFrameCallback在WindowAnimator构造器中赋值:
mAnimationFrameCallback = frameTimeNs -> {
synchronized (mService.mGlobalLock) {
mAnimationFrameCallbackScheduled = false;
animate(frameTimeNs);
if (mNotifyWhenNoAnimation && !mLastRootAnimating) {
mService.mGlobalLock.notifyAll();
}
}
};
每次被Choreographer回调时都会调用WindowAnimator的animate方法:
private void animate(long frameTimeNs) {
if (!mInitialized) {
return;
}
// Schedule next frame already such that back-pressure happens continuously.
scheduleAnimation();
mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
if (DEBUG_WINDOW_TRACE) {
Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
}
ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION animate");
mService.openSurfaceTransaction();
try {
final AccessibilityController accessibilityController =
mService.mAccessibilityController;
final int numDisplays = mDisplayContentsAnimators.size();
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
// Update animations of all applications, including those associated with
// exiting/removed apps.
dc.updateWindowsForAnimator();
dc.prepareSurfaces();
}
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
dc.checkAppWindowsReadyToShow();
if (accessibilityController != null) {
accessibilityController.drawMagnifiedRegionBorderIfNeededLocked(displayId,
mTransaction);
}
}
cancelAnimation();
if (mService.mWatermark != null) {
mService.mWatermark.drawIfNeeded();
}
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
}
final boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
final boolean doRequest = mBulkUpdateParams != 0 && mService.mRoot.copyAnimToLayoutParams();
if (hasPendingLayoutChanges || doRequest) {
mService.mWindowPlacerLocked.requestTraversal();
}
final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */,
ANIMATION_TYPE_ALL /* typesToCheck */);
if (rootAnimating && !mLastRootAnimating) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
}
if (!rootAnimating && mLastRootAnimating) {
mService.mWindowPlacerLocked.requestTraversal();
Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
}
mLastRootAnimating = rootAnimating;
final boolean runningExpensiveAnimations =
mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */,
ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_SCREEN_ROTATION
| ANIMATION_TYPE_RECENTS /* typesToCheck */);
if (runningExpensiveAnimations && !mRunningExpensiveAnimations) {
// Usually app transitions put quite a load onto the system already (with all the things
// happening in app), so pause task snapshot persisting to not increase the load.
mService.mTaskSnapshotController.setPersisterPaused(true);
mTransaction.setEarlyWakeupStart();
} else if (!runningExpensiveAnimations && mRunningExpensiveAnimations) {
mService.mTaskSnapshotController.setPersisterPaused(false);
mTransaction.setEarlyWakeupEnd();
}
mRunningExpensiveAnimations = runningExpensiveAnimations;
SurfaceControl.mergeToGlobalTransaction(mTransaction);
mService.closeSurfaceTransaction("WindowAnimator");
ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
if (mRemoveReplacedWindows) {
mService.mRoot.removeReplacedWindows();
mRemoveReplacedWindows = false;
}
mService.destroyPreservedSurfaceLocked();
executeAfterPrepareSurfacesRunnables();
if (DEBUG_WINDOW_TRACE) {
Slog.i(TAG, "!!! animate: exit"
+ " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
+ " hasPendingLayoutChanges=" + hasPendingLayoutChanges);
}
}
WindowStateAnimator
WindowStateAnimator定义在frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java。
在frameworks/base/services/core/java/com/android/server/wm/WindowState.java类中有一个类型为WindowStateAnimator的成员变量mWinAnimator,用来处理窗口动画相关逻辑。
SurfaceAnimator
SurfaceAnimator定义在frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimator.java。
在frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java中有一个类型为SurfaceAnimator的成员变量mSurfaceAnimator。
首先可以通过SurfaceAnimator的注释了解Leash:
/**
* A class that can run animations on objects that have a set of child surfaces. We do this by
* reparenting all child surfaces of an object onto a new surface, called the "Leash". The Leash
* gets attached in the surface hierarchy where the the children were attached to. We then hand off
* the Leash to the component handling the animation, which is specified by the
* {@link AnimationAdapter}. When the animation is done animating, our callback to finish the
* animation will be invoked, at which we reparent the children back to the original parent.
*/
class SurfaceAnimator {
SurfaceAnimator的startAnimation方法中创建Leash:
/**
* Starts an animation.
*
* @param anim The object that bridges the controller, {@link SurfaceAnimator}, with the
* component responsible for running the animation. It runs the animation with
* {@link AnimationAdapter#startAnimation} once the hierarchy with
* the Leash has been set up.
* @param hidden Whether the container holding the child surfaces is currently visible or not.
* This is important as it will start with the leash hidden or visible before
* handing it to the component that is responsible to run the animation.
* @param animationFinishedCallback The callback being triggered when the animation finishes.
*/
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
@AnimationType int type,
@Nullable OnAnimationFinishedCallback animationFinishedCallback,
@Nullable SurfaceFreezer freezer) {
cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
mAnimation = anim;
mAnimationType = type;
mAnimationFinishedCallback = animationFinishedCallback;
final SurfaceControl surface = mAnimatable.getSurfaceControl();
if (surface == null) {
Slog.w(TAG, "Unable to start animation, surface is null or no children.");
cancelAnimation();
return;
}
mLeash = freezer != null ? freezer.takeLeashForAnimation() : null;
if (mLeash == null) {
mLeash = createAnimationLeash(mAnimatable, surface, t, type,
mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
0 /* y */, hidden, mService.mTransactionFactory);
mAnimatable.onAnimationLeashCreated(t, mLeash);
}
mAnimatable.onLeashAnimationStarting(t, mLeash);
if (mAnimationStartDelayed) {
if (DEBUG_ANIM) Slog.i(TAG, "Animation start delayed");
return;
}
mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
}
最后调用了AnimationAdapter的startAnimation方法。
SurfaceAnimator.Animatable
SurfaceAnimator有一个类型为Animatable的成员变量mAnimatable,Animatable是定义在SurfaceAnimator类中的内部接口:
/**
* Interface to be animated by {@link SurfaceAnimator}.
*/
interface Animatable {
/**
* @return The pending transaction that will be committed in the next frame.
*/
@NonNull Transaction getPendingTransaction();
/**
* Schedules a commit of the pending transaction.
*/
void commitPendingTransaction();
/**
* Called when the animation leash is created. Note that this is also called by
* {@link SurfaceFreezer}, so this doesn't mean we're about to start animating.
*
* @param t The transaction to use to apply any necessary changes.
* @param leash The leash that was created.
*/
void onAnimationLeashCreated(Transaction t, SurfaceControl leash);
/**
* Called when the animator is about to start animating the leash.
*
* @param t The transaction to use to apply any necessary changes.
* @param leash The leash that was created.
*/
default void onLeashAnimationStarting(Transaction t, SurfaceControl leash) { }
/**
* Called when the leash is being destroyed, or when the leash is being transferred to
* another SurfaceAnimator.
*
* @param t The transaction to use to apply any necessary changes.
*/
void onAnimationLeashLost(Transaction t);
/**
* @return A new surface to be used for the animation leash, inserted at the correct
* position in the hierarchy.
*/
SurfaceControl.Builder makeAnimationLeash();
/**
* @return The parent that should be used for the animation leash.
*/
@Nullable SurfaceControl getAnimationLeashParent();
/**
* @return The surface of the object to be animated.
* This SurfaceControl must be valid if non-null.
*/
@Nullable SurfaceControl getSurfaceControl();
/**
* @return The parent of the surface object to be animated.
* This SurfaceControl must be valid if non-null.
*/
@Nullable SurfaceControl getParentSurfaceControl();
/**
* @return The width of the surface to be animated.
*/
int getSurfaceWidth();
/**
* @return The height of the surface to be animated.
*/
int getSurfaceHeight();
/**
* Gets called when the animation is about to finish and gives the client the opportunity to
* defer finishing the animation, i.e. it keeps the leash around until the client calls
* {@link #cancelAnimation}.
* <p>
* {@link AnimationAdapter} has a similar method which is called only if this method returns
* false. This mean that if both this {@link Animatable} and the {@link AnimationAdapter}
* request to be deferred, this method is the sole responsible to call
* endDeferFinishCallback. On the other hand, the animation finish might still be deferred
* if this method return false and the one from the {@link AnimationAdapter} returns true.
*
* @param endDeferFinishCallback The callback to call when defer finishing should be ended.
* @return Whether the client would like to defer the animation finish.
*/
default boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
return false;
}
}
WindowContainer本身实现了Animatable接口,并且在其构造器中创建SurfaceAnimator的时候,将自己作为Animatable传给了SurfaceAnimator:
WindowContainer(WindowManagerService wms) {
mWmService = wms;
mPendingTransaction = wms.mTransactionFactory.get();
mBLASTSyncTransaction = wms.mTransactionFactory.get();
mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, wms); // 第一个参数是Aniamtable
mSurfaceFreezer = new SurfaceFreezer(this, wms);
}
因此WindowContainer.mSurfaceAnimator.mAnimatable就是WindowContainer自己。
AnimationAdapter
AnimationAdapter是一个接口,定义在frameworks/base/services/core/java/com/android/server/wm/AnimationAdapter.java:
/**
* Interface that describes an animation and bridges the animation start to the component
* responsible for running the animation.
*/
interface AnimationAdapter {
long STATUS_BAR_TRANSITION_DURATION = 120L;
/**
* @return Whether we should show the wallpaper during the animation.
* @see Animation#getShowWallpaper()
*/
boolean getShowWallpaper();
/**
* Requests to start the animation.
*
* @param animationLeash The surface to run the animation on. See {@link SurfaceAnimator} for an
* overview of the mechanism. This surface needs to be released by the
* component running the animation after {@code finishCallback} has been
* invoked, or after the animation was cancelled.
* @param t The Transaction to apply the initial frame of the animation.
* @param type The type of the animation.
* @param finishCallback The callback to be invoked when the animation has finished.
*/
void startAnimation(SurfaceControl animationLeash, Transaction t, @AnimationType int type,
OnAnimationFinishedCallback finishCallback);
/**
* Called when the animation that was started with {@link #startAnimation} was cancelled by the
* window manager.
*
* @param animationLeash The leash passed to {@link #startAnimation}.
*/
void onAnimationCancelled(SurfaceControl animationLeash);
/**
* @return The approximate duration of the animation, in milliseconds.
*/
long getDurationHint();
/**
* If this animation is run as an app opening animation, this calculates the start time for all
* status bar transitions that happen as part of the app opening animation, which will be
* forwarded to SystemUI.
*
* @return the desired start time of the status bar transition, in uptime millis
*/
long getStatusBarTransitionsStartTime();
void dump(PrintWriter pw, String prefix);
default void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
dumpDebug(proto);
proto.end(token);
}
void dumpDebug(ProtoOutputStream proto);
/**
* Gets called when the animation is about to finish and gives the client the opportunity to
* defer finishing the animation, i.e. it keeps the leash around until the client calls
* endDeferFinishCallback.
* <p>
* This has the same effect as
* {@link com.android.server.wm.SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable)}
* . The later will be evaluated first and has precedence over this method if it returns true,
* which means that if the {@link com.android.server.wm.SurfaceAnimator.Animatable} requests to
* defer its finish, this method won't be called so this adapter will never have access to the
* finish callback. On the other hand, if the
* {@link com.android.server.wm.SurfaceAnimator.Animatable}, doesn't request to defer, this
* {@link AnimationAdapter} is responsible for ending the animation.
*
* @param endDeferFinishCallback The callback to call when defer finishing should be ended.
* @return Whether the client would like to defer the animation finish.
*/
default boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
return false;
}
}
LocalAnimationAdapter
LocalAnimationAdapter定义在frameworks/base/services/core/java/com/android/server/wm/LocalAnimationAdapter.java,实现了AnimationAdapter接口,其成员变量、构造函数和startAnimation方法如下:
/**
* Animation that can be executed without holding the window manager lock. See
* {@link SurfaceAnimationRunner}.
*/
class LocalAnimationAdapter implements AnimationAdapter {
private final AnimationSpec mSpec;
private final SurfaceAnimationRunner mAnimator;
LocalAnimationAdapter(AnimationSpec spec, SurfaceAnimationRunner animator) {
mSpec = spec;
mAnimator = animator;
}
......
@Override
public void startAnimation(SurfaceControl animationLeash, Transaction t,
@AnimationType int type, OnAnimationFinishedCallback finishCallback) {
mAnimator.startAnimation(mSpec, animationLeash, t,
() -> finishCallback.onAnimationFinished(type, this));
}
......
}
其startAnimation方法最后调用了类型为SurfaceAnimationRunner的成员变量mAnimator的startAnimation方法。
LocalAnimationAdapter.AnimationSpec
LocalAnimationAdapter有一个内部接口AnimationSpec定义如下:
/**
* Describes how to apply an animation.
*/
interface AnimationSpec {
/**
* @see AnimationAdapter#getShowWallpaper
*/
default boolean getShowWallpaper() {
return false;
}
/**
* @see AnimationAdapter#getStatusBarTransitionsStartTime
*/
default long calculateStatusBarTransitionStartTime() {
return SystemClock.uptimeMillis();
}
/**
* @return The duration of the animation.
*/
long getDuration();
/**
* Called when the spec needs to apply the current animation state to the leash.
*
* @param t The transaction to use to apply a transform.
* @param leash The leash to apply the state to.
* @param currentPlayTime The current time of the animation.
*/
void apply(Transaction t, SurfaceControl leash, long currentPlayTime);
/**
* @see AppTransition#canSkipFirstFrame
*/
default boolean canSkipFirstFrame() {
return false;
}
/**
* @return {@code true} if we need to wake-up SurfaceFlinger earlier during this animation.
*
* @see Transaction#setEarlyWakeup
*/
default boolean needsEarlyWakeup() { return false; }
/**
* @return The fraction of the animation, returns 1 if duration is 0.
*
* @param currentPlayTime The current play time.
*/
default float getFraction(float currentPlayTime) {
final float duration = getDuration();
return duration > 0 ? currentPlayTime / duration : 1.0f;
}
void dump(PrintWriter pw, String prefix);
default void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
dumpDebugInner(proto);
proto.end(token);
}
void dumpDebugInner(ProtoOutputStream proto);
}
SurfaceAnimationRunner
SurfaceAnimationRunner定义在frameworks/base/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java。
有一个类型为ArrayMap<SurfaceControl, RunningAnimation>的成员变量mPendingAnimations。
其中SurfaceAnimationRunner的内部静态类RunningAnimation定义如下:
private static final class RunningAnimation {
final AnimationSpec mAnimSpec;
final SurfaceControl mLeash;
final Runnable mFinishCallback;
ValueAnimator mAnim;
@GuardedBy("mCancelLock")
private boolean mCancelled;
RunningAnimation(AnimationSpec animSpec, SurfaceControl leash, Runnable finishCallback) {
mAnimSpec = animSpec;
mLeash = leash;
mFinishCallback = finishCallback;
}
}
在SurfaceAnimationRunner的startAnimation方法中加入mPendingAnimations并注册Choreographer回调this::startAnimations方法,还进行了第一次变换计算:
void startAnimation(AnimationSpec a, SurfaceControl animationLeash, Transaction t,
Runnable finishCallback) {
synchronized (mLock) {
final RunningAnimation runningAnim = new RunningAnimation(a, animationLeash,
finishCallback);
mPendingAnimations.put(animationLeash, runningAnim);
if (!mAnimationStartDeferred) {
mChoreographer.postFrameCallback(this::startAnimations);
}
// Some animations (e.g. move animations) require the initial transform to be applied
// immediately.
applyTransformation(runningAnim, t, 0 /* currentPlayTime */);
}
}
SurfaceAnimationRunner的startAnimations方法调用了SurfaceAnimationRunner的startPendingAnimationsLocked方法,其又调用了SurfaceAnimationRunner的startAnimationLocked方法:
private void startAnimations(long frameTimeNanos) {
synchronized (mLock) {
startPendingAnimationsLocked();
}
mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
}
@GuardedBy("mLock")
private void startPendingAnimationsLocked() {
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
startAnimationLocked(mPendingAnimations.valueAt(i));
}
mPendingAnimations.clear();
}
@GuardedBy("mLock")
private void startAnimationLocked(RunningAnimation a) {
final ValueAnimator anim = mAnimatorFactory.makeAnimator();
// Animation length is already expected to be scaled.
anim.overrideDurationScale(1.0f);
anim.setDuration(a.mAnimSpec.getDuration());
anim.addUpdateListener(animation -> {
synchronized (mCancelLock) {
if (!a.mCancelled) {
final long duration = anim.getDuration();
long currentPlayTime = anim.getCurrentPlayTime();
if (currentPlayTime > duration) {
currentPlayTime = duration;
}
applyTransformation(a, mFrameTransaction, currentPlayTime);
}
}
// Transaction will be applied in the commit phase.
scheduleApplyTransaction();
});
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
synchronized (mCancelLock) {
if (!a.mCancelled) {
// TODO: change this back to use show instead of alpha when b/138459974 is
// fixed.
mFrameTransaction.setAlpha(a.mLeash, 1);
}
}
}
@Override
public void onAnimationEnd(Animator animation) {
synchronized (mLock) {
mRunningAnimations.remove(a.mLeash);
synchronized (mCancelLock) {
if (!a.mCancelled) {
// Post on other thread that we can push final state without jank.
mAnimationThreadHandler.post(a.mFinishCallback);
}
}
}
}
});
a.mAnim = anim;
mRunningAnimations.put(a.mLeash, a);
anim.start();
if (a.mAnimSpec.canSkipFirstFrame()) {
// If we can skip the first frame, we start one frame later.
anim.setCurrentPlayTime(mChoreographer.getFrameIntervalNanos() / NANOS_PER_MS);
}
// Immediately start the animation by manually applying an animation frame. Otherwise, the
// start time would only be set in the next frame, leading to a delay.
anim.doAnimationFrame(mChoreographer.getFrameTime());
}
通过ValueAnimator的start方法开始动画,动画过程中通过调用applyTransformation计算变换:
private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) {
a.mAnimSpec.apply(t, a.mLeash, currentPlayTime);
}
调用了RunningAnimation中类型为AnimationSpec的成员变量mAnimSpec的apply方法计算变换。
IRemoteAnimationRunner
IRemoteAnimationRunner定义在frameworks/base/core/java/android/view/IRemoteAnimationRunner.aidl,这个aidl接口可以用来通过binder跨进程控制动画的执行过程,定义如下:
/**
* Interface that is used to callback from window manager to the process that runs a remote
* animation to start or cancel it.
*
* {@hide}
*/
oneway interface IRemoteAnimationRunner {
/**
* Called when the process needs to start the remote animation.
*
* @param apps The list of apps to animate.
* @param finishedCallback The callback to invoke when the animation is finished.
*/
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
void onAnimationStart(in RemoteAnimationTarget[] apps, in RemoteAnimationTarget[] wallpapers,
in IRemoteAnimationFinishedCallback finishedCallback);
/**
* Called when the animation was cancelled. From this point on, any updates onto the leashes
* won't have any effect anymore.
*/
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
void onAnimationCancelled();
}
RemoteAnimationAdapter
RemoteAnimationAdapter定义在frameworks/base/core/java/android/view/RemoteAnimationAdapter.java,有一个类型为IRemoteAnimationRunner的成员变量mRunner,还有一些例如动画持续时间等属性。
例如点击Notification时在systemui进程执行启动Activity的远程动画的部分流程是:
-
创建继承IRemoteAnimationRunner.Stub的对象runner;
-
创建RemoteAnimationAdapter对象adapter包装runner,同时设置持续时间等属性;
-
通过ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart(package, adapter)方法在system_server中注册远程动画。
动画分类
安卓动画主要有:
1 过渡动画
2 窗口动画
3 转屏动画
等等。这里总结的还不完全有待补充。