安卓动画系统 - 安卓R

重要类介绍

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的远程动画的部分流程是:

  1. 创建继承IRemoteAnimationRunner.Stub的对象runner;

  2. 创建RemoteAnimationAdapter对象adapter包装runner,同时设置持续时间等属性;

  3. 通过ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart(package, adapter)方法在system_server中注册远程动画。

动画分类

安卓动画主要有:

1 过渡动画

2 窗口动画

3 转屏动画

等等。这里总结的还不完全有待补充。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值