动画原理
动画本质上是,随着时间的流逝,施加不同的变化于窗口的 Surface.
AnimationSpec 接口,定义动画如何运行,包括运行时长、当前时间比例等,以及在不同的时间点上,通过事务施加不同的变形于Surface.
Animation 类提供起始值、结束值、插值器、Transformation 等;Transformation 包括 Matrix, Alpha.
public class WindowAnimationSpec implements AnimationSpec {
// 定义起始值、结束值、运行时长、插值器等;
private Animation mAnimation;
@Override
public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) {
final TmpValues tmp = mThreadLocalTmps.get();
tmp.transformation.clear();
// 获取当前运行时间点的 Transformation
mAnimation.getTransformation(currentPlayTime, tmp.transformation);
tmp.transformation.getMatrix().postTranslate(mPosition.x, mPosition.y);
// 通过 Transaction 修改 Surface
t.setMatrix(leash, tmp.transformation.getMatrix(), tmp.floats);
t.setAlpha(leash, tmp.transformation.getAlpha());
}
}
SurfaceAnimationRunner 类驱动动画运行,以及提交Surface的事务。 SurfaceAnimationRunner 通过 ValueAnimator 驱动动画,ValueAnimator 内部包装 Choreograher 对象,请求下一帧的回调并继续运行动画。SurfaceAnimationRunner 类内部的 Choreograher 对象用于在下一帧的回调中提交事务。
class SurfaceAnimationRunner {
private void startAnimationLocked(RunningAnimation a) {
final ValueAnimator anim = mAnimatorFactory.makeAnimator();
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;
}
// 在每一帧中,调用 AnimationSpec 的 apply 方法
applyTransformation(a, mFrameTransaction, currentPlayTime);
}
}
// 在下一帧使 Surface 的事务生效
scheduleApplyTransaction();
});
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
synchronized (mCancelLock) {
if (!a.mCancelled) {
// 动画开始时,显示Surface
mFrameTransaction.setAlpha(a.mLeash, 1);
}
}
}
@Override
public void onAnimationEnd(Animator animation) {
synchronized (mLock) {
mRunningAnimations.remove(a.mLeash);
synchronized (mCancelLock) {
if (!a.mCancelled) {
mAnimationThreadHandler.post(a.mFinishCallback);
}
}
}
}
});
a.mAnim = anim;
mRunningAnimations.put(a.mLeash, a);
anim.start();
...
// 立即开始动画
anim.doAnimationFrame(mChoreographer.getFrameTime());
}
// 在 Choreograher 回调方法使 Transaction 生效
private final Runnable mApplyTransactionRunnable = this::applyTransaction;
private void applyTransaction() {
mFrameTransaction.setAnimationTransaction();
mFrameTransaction.setFrameTimelineVsync(mChoreographer.getVsyncId());
mFrameTransaction.apply();
mApplyScheduled = false;
}
}
SurfaceAnimator 创建和销毁 Leash, reparent 动画窗口的Surface. 并且作用动画于 Leash. AnimationAdapter 是 SurfaceAnimationRunner 与 AnimationSpec 之间的适配器。
static SurfaceControl createAnimationLeash(Animatable animatable, SurfaceControl surface,
Transaction t, @AnimationType int type, int width, int height, int x, int y,
boolean hidden, Supplier<Transaction> transactionFactory) {
// 1. 创建 Leash
final SurfaceControl.Builder builder = animatable.makeAnimationLeash()
.setParent(animatable.getAnimationLeashParent())
.setName(surface + " - animation-leash of " + animationTypeToString(type))
.setHidden(hidden)
.setEffectLayer()
.setCallsite("SurfaceAnimator.createAnimationLeash");
final SurfaceControl leash = builder.build();
// 2. 设置 Leash 的大小、位置、可见性;
t.setWindowCrop(leash, width, height);
t.setPosition(leash, x, y);
t.show(leash);
t.setAlpha(leash, hidden ? 0 : 1);
// 3. 设置 Leash 为动画 Surface 的 parent
t.reparent(surface, leash);
return leash;
}
开始动画时,创建Leash, 并在Surface层次结构中,使动画窗口的Surface reparent 到Leash上,作用动画于 Leash.
void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
@AnimationType int type,
@Nullable OnAnimationFinishedCallback animationFinishedCallback,
@Nullable Runnable animationCancelledCallback,
@Nullable AnimationAdapter snapshotAnim, @Nullable SurfaceFreezer freezer) {
cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
mAnimation = anim;
mAnimationType = type;
mSurfaceAnimationFinishedCallback = animationFinishedCallback;
mAnimationCancelledCallback = animationCancelledCallback;
final SurfaceControl surface = mAnimatable.getSurfaceControl();
...
// 1. 创建 Leash
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);
...
// 2. 开始动画
mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
...
}
在动画结束的回调中销毁 Leash, 并reparent窗口的Surface到原来的层次结构。
private OnAnimationFinishedCallback getFinishedCallback(
@Nullable OnAnimationFinishedCallback staticAnimationFinishedCallback) {
return (type, anim) -> {
synchronized (mService.mGlobalLock) {
...
final Runnable resetAndInvokeFinish = () -> {
...
// 调用 removeLeash() 销毁 Leash
reset(mAnimatable.getSyncTransaction(), true /* destroyLeash */);
...
};
// 调用 resetAndInvokeFinish
if (!(mAnimatable.shouldDeferAnimationFinish(resetAndInvokeFinish)
|| anim.shouldDeferAnimationFinish(resetAndInvokeFinish))) {
resetAndInvokeFinish.run();
}
mAnimationFinished = true;
}
};
}
static boolean removeLeash(Transaction t, Animatable animatable, @NonNull SurfaceControl leash,
boolean destroy) {
boolean scheduleAnim = false;
final SurfaceControl surface = animatable.getSurfaceControl();
// 动画窗口的父窗口对应的Surface
final SurfaceControl parent = animatable.getParentSurfaceControl();
final SurfaceControl curAnimationLeash = animatable.getAnimationLeash();
final boolean reparent = surface != null && (curAnimationLeash == null
|| curAnimationLeash.equals(leash));
if (reparent) {
if (surface.isValid() && parent != null && parent.isValid()) {
// 恢复 Surface 的层级关系
t.reparent(surface, parent);
scheduleAnim = true;
}
}
// 销毁 Leash
if (destroy) {
t.remove(leash);
scheduleAnim = true;
}
...
return scheduleAnim;
}