概览

窗口过渡动画包含窗口启动、窗口退出和窗口大小变化。Google 在 Android 12 开始引入 TransitionPlayer 后,一个全新的过渡动画框架,Android 14 正式启用了该框架。即然是 Android 重新设计的窗口过渡动画框架,我们默认该框架比旧框架更优秀,我们的窗口过渡动画也会参考该框架。

Android 流程

sequenceDiagram

box ActivityManager
participant ar as ActivityRecord
participant as as ActivityStarter
end

box WindowManager
participant tc as TransitionController
participant t as Transition
participant woc as IWindowOrganizerController
end

box SystemUI
participant tp as ITransitionPlayer
end

box Launcher
participant rt as IRemoteTransition
end

tp ->> woc : registerTransitionPlayer()

Note over as : startActivityUnchecked()
as ->> tc : createTransition(TRANSIT_OPEN)
tc ->> t : new
as ->> tc : collect()

as ->> tc : requestStartTransition()
tc ->>+ tp : requestStartTransition()
tp ->>- woc : startTransition()
woc ->> t : start()

Note over t : WAIT DRAWING
t ->> woc : onTransitionReady()
woc ->> tp : onTransitionReady()
tp ->> rt : startAnimation()

Note over rt : ANIMATING

rt ->> tp : onTransitionFinished()
tp ->> woc : finishTransition()
woc ->> tc : finishTransition()
tc ->> t : finishTransiton()
t ->> ar : commitVisibility(false)

过渡动画相关模块主要有 3 个部分:ActivityManager、WindowManager 和 SystemUI,如果是一个远程过渡动画,则包含 Launcher。

流程步骤如下所示:

  1. ActivityManager 启动 Activity 过程中创建 Transition。
  2. 搜集需要做动画的窗口。
  3. 请求开始过渡动画。
    1. WindowManager 请求 SystemUI 开始过渡动画。
    2. SystemUI 完成准备工作后通知 WindowManager 过渡动画开始。
  4. WindowManager 等待窗口绘制完成。
  5. 窗口绘制完成后通知 SystemUI 过渡动画准备完成。
    1. SystemUI 调度过渡动画,执行动画。
    2. 如果是远程动画,把动画信息发送给 Launcher。
  6. 动画结束后 SystemUI 通知 WindowManager。
    1. WindowManager 通知后台 Activity 不可见。

模块

参考 Android 框架,分为 4 个模块,ApplicationManager、TransitionController、TransitionPlayer 和 RemoteTransition。

graph TB

ApplicationManager -- create/collect/request --> TransitionController
TransitionController -- finish --> ApplicationManager

TransitionController -- request/ready --> TransitionPlayer
TransitionPlayer -- start/finish --> TransitionController
TransitionController -- wait draw --> TransitionController

TransitionPlayer -- animate --> RemoteTransition
RemoteTransition -- finish --> TransitionPlayer

ApplicationManager: