动画类型
WMS动画类型定义在 SurfaceAnimator, 下面分别分析窗口动画、Activity切换动画、转屏动画的流程。
class SurfaceAnimator {
/**
* The type of the animation.
* @hide
*/
@IntDef(flag = true, prefix = { "ANIMATION_TYPE_" }, value = {
ANIMATION_TYPE_NONE,
ANIMATION_TYPE_APP_TRANSITION,
ANIMATION_TYPE_SCREEN_ROTATION,
ANIMATION_TYPE_DIMMER,
ANIMATION_TYPE_RECENTS,
ANIMATION_TYPE_WINDOW_ANIMATION,
ANIMATION_TYPE_INSETS_CONTROL,
ANIMATION_TYPE_TOKEN_TRANSFORM,
ANIMATION_TYPE_STARTING_REVEAL,
ANIMATION_TYPE_PREDICT_BACK
})
@Retention(RetentionPolicy.SOURCE)
@interface AnimationType {}
}
窗口动画流程
所有动画都是通过创建 AnimationSpec 和 AnimationAdapter,并交给 SurfaceAnimator 去执行。
窗口动画的类型定义在 WindowManagerPolicy.
public interface WindowManagerPolicy {
// 第一次显示
public static final int TRANSIT_ENTER = 1;
// 退出
public static final int TRANSIT_EXIT = 2;
// 显示
public static final int TRANSIT_SHOW = 3;
// 未使用
public static final int TRANSIT_HIDE = 4;
// 应用启动窗口退出
public static final int TRANSIT_PREVIEW_DONE = 5;
}
WindowStateAnimator 类负责跟踪窗口动画,动画执行流程如下:
- applyAnimationLocked() 根据窗口动画类型选择并加载动画资源文件,生成 Animation 对象;
- 在 WindowState 的 startAnimation() 方法创建 AnimationSpec 和 AniamtionAdapter 对象;
- 交给 SurfaceAnimator 执行动画。
class WindowStateAnimator {
void applyEnterAnimationLocked() {
final int transit;
// addWindow() 中设置 mEnterAnimationPending 为 ture,
// 第一次显示为入场动画(TRANSIT_ENTER),其它为 TRANSIT_SHOW
// addWindow() 中置为 true
if (mEnterAnimationPending) {
mEnterAnimationPending = false;
transit = WindowManagerPolicy.TRANSIT_ENTER;
} else {
transit = WindowManagerPolicy.TRANSIT_SHOW;
}
// Activity 动画由 ActivityRecord 控制, 壁纸的动画由 WallpaperController 控制
if (mAttrType != TYPE_BASE_APPLICATION && !mIsWallpaper) {
applyAnimationLocked(transit, true);
}
...
}
boolean applyAnimationLocked(int transit, boolean isEntrance) {
...
// 屏幕没有冻结
if (mWin.mToken.okToAnimate()) {
int anim = mWin.getDisplayContent().getDisplayPolicy().selectAnimation(mWin, transit);
int attr = -1;
Animation a = null;
if (anim != DisplayPolicy.ANIMATION_STYLEABLE) {
if (anim != DisplayPolicy.ANIMATION_NONE) {
a = AnimationUtils.loadAnimation(mContext, anim);
}
} else {
switch (transit) {
case WindowManagerPolicy.TRANSIT_ENTER:
attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
break;
case WindowManagerPolicy.TRANSIT_EXIT:
attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
break;
case WindowManagerPolicy.TRANSIT_SHOW:
attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
break;
case WindowManagerPolicy.TRANSIT_HIDE:
attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
break;
}
if (attr >= 0) {
a = mWin.getDisplayContent().mAppTransition.loadAnimationAttr(
mWin.mAttrs, attr, TRANSIT_OLD_NONE);
}
}
if (a != null) {
mWin.startAnimation(a);
mAnimationIsEntrance = isEntrance;
}
} else {
mWin.cancelAnimation();
}
return mWin.isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION);
}
}
WindowState
class WindowState {
void startAnimation(Animation anim) {
...
final DisplayInfo displayInfo = getDisplayInfo();
// 1. 初始化 Animation 对象,设置最大运行时长
anim.initialize(mWindowFrames.mFrame.width(), mWindowFrames.mFrame.height(),
displayInfo.appWidth, displayInfo.appHeight);
anim.restrictDuration(MAX_ANIMATION_DURATION);
anim.scaleCurrentDuration(mWmService.getWindowAnimationScaleLocked());
// 2. 创建 WindowAnimationSpec, LocalAnimationAdapter 对象
final AnimationAdapter adapter = new LocalAnimationAdapter(
new WindowAnimationSpec(anim, mSurfacePosition, false /* canSkipFirstFrame */,
0 /* windowCornerRadius */),
mWmService.mSurfaceAnimationRunner);
// 3. 通过 SurfaceAnimator 执行动画
startAnimation(getPendingTransaction(), adapter);
commitPendingTransaction();
}
}