本文摘要:onTransitionReady是Android窗口过渡动画的核心触发机制,其流程为:1)Activity启动时创建Transition并开始收集参与者;2)通过BLASTSyncEngine同步所有Surface绘制;3)当所有参与者完成绘制后,系统回调onTransactionReady;4)Transition合并所有Surface事务后,调用ShellTransitionPlayer.onTransitionReady通知Shell进程;5)Shell接收到包含动画信息的TransitionInfo后执行动画。整个过程涉及Launcher、WMS、SurfaceFlinger和Shell进程的协作,确保窗口切换时的平滑过渡效果。
onTransitionReady 完整触发流程
┌─────────────────────────────────────────────────────────────────────────────────┐
│ onTransitionReady 触发时序 │
└─────────────────────────────────────────────────────────────────────────────────┘
1️⃣ [ActivityStarter] 时间点:startActivity() 时
│
│ 创建 Transition 并开始收集
▼
2️⃣ [Transition.startCollecting()] Line 718
│
│ 调用 mSyncEngine.startSyncSet(this, ...)
│ this = TransactionReadyListener
▼
3️⃣ [BLASTSyncEngine] 等待所有参与者的 Surface 同步完成
│
│ Apps 绘制完成后 SurfaceFlinger 通知
▼
4️⃣ [BLASTSyncEngine.onTransactionReady()] Line 291
│
│ 回调 mListener.onTransactionReady(syncId, transaction)
│ 即 Transition.onTransactionReady()
▼
5️⃣ [Transition.onTransactionReady()] Line 1788
│
│ 构建 TransitionInfo
│ 合并所有 Surface transactions
▼
6️⃣ [Transition.onTransactionReady()] Line 1998
│
│ 调用 mController.getTransitionPlayer().onTransitionReady()
│ │
│ ▼
7️⃣ [Shell TransitionPlayer.onTransitionReady()] ◄── Shell 收到通知!
│
│ Shell 开始执行动画
▼
8️⃣ [动画播放完成] → Shell 通知 WMS → 动画结束
Transition 开始收集
void startCollecting(long timeoutMs) {
mState = STATE_COLLECTING;
// 注册为 TransactionReadyListener
mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, ...);
}
作用 :注册 Transition 自身作为同步监听器
BLASTSyncEngine 同步完成
// 当所有参与者都准备好时,触发回调
mListener.onTransactionReady(mSyncId, merged);
Transition 收到同步完成通知
@Override
public void onTransactionReady(int syncId, SurfaceControl.Transaction transaction) {
// ... 状态检查 ...
// 构建 TransitionInfo(包含所有需要动画的元素)
calculateTransitionInfo();
// 合并所有 Surface transactions
mergeTransactions(transaction);
// ◄── 关键点:通知 Shell
mController.getTransitionPlayer().onTransitionReady(
mToken, // Transition token
info, // TransitionInfo(包含动画信息)
transaction, // 当前 Surface transaction
mFinishTransaction); // 完成时的 transaction
}
什么条件触发 onTransitionReady ?
必须满足的条件:
-
Transition 处于 COLLECTING 状态 - 已调用 startCollecting()
-
所有参与者都报告完成 - BLASTSyncEngine 收到所有 onTransactionReady() 回调
-
Shell TransitionPlayer 存在 - mController.getTransitionPlayer() != null
-
Player 启用 - mIsPlayerEnabled == true
状态转换图
┌─────────────┐
│ STATE_PENDING │ 创建时
└──────┬──────┘
│ startCollecting()
▼
┌─────────────┐
┌─────────│ STATE_COLLECTING │ 等待同步
│ └──────┬──────┘
│ │ onTransactionReady() 所有参与者都同步完成
│ ▼
│ ┌─────────────┐
│ │ STATE_STARTED │ 已经开始播放(调用start())
│ └──────┬──────┘
│ │ 动画执行完成
│ ▼
│ ┌─────────────┐
└────────▶│ STATE_PLAYING │ 播放中
└──────┬──────┘
│
▼
┌─────────────┐
│ STATE_FINISHED │ 动画完成
└─────────────┘
实际启动场景中的时序
┌────────────┐ ┌─────────────────┐ ┌──────────────┐ ┌────────────────┐
│ Launcher │ │ system_server │ │ Surface │ │ wm/shell │
│ 进程 │ │ WMS │ │ Flinger │ │ 进程 │
└─────┬──────┘ └────────┬────────┘ └──────┬───────┘ └───────┬────────┘
│ │ │ │
│ startActivity() │ │ │
│─────────────────────▶│ │ │
│ │ │ │
│ │ startCollecting() │ │
│ │──┐ │ │
│ │ │ │ │
│ │◀─┘ │ │
│ │ │ │
│ App绘制... │ │ │
│◀─────────────────────│ │ │
│ │ │ │
│ Buffer释放 │ │ │
│─────────────────────▶│ │ │
│ │ │ │
│ │ onTransactionReady │ │
│ │◀────────────────────│ │
│ │ │ │
│ │ onTransitionReady │ │
│ │────────────────────▶│ │
│ │ │ │
│ │ │ 执行动画... │
│ │ │◀────────────────────│
│ │ │ │
│ │◀───────────────────│ 动画完成 │
│◀─────────────────────│ │ │
│ Activity RESUMED │ │ │
│ │ │ │
总结

简而言之 : onTransitionReady 是在所有参与动画的 Surface 都完成绘制(同步)后,由 BLASTSyncEngine 回调 Transition.onTransactionReady() ,然后再通知 Shell 开始执行动画。