Android 理解onTransitionReady(一)

本文摘要: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 ?

必须满足的条件:

  1. Transition 处于 COLLECTING 状态 - 已调用 startCollecting()

  2. 所有参与者都报告完成 - BLASTSyncEngine 收到所有 onTransactionReady() 回调

  3. Shell TransitionPlayer 存在 - mController.getTransitionPlayer() != null

  4. 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 开始执行动画。

相关推荐
流星白龙1 小时前
【MySQL高阶】2.MySQL命令行客户端(2)
android·mysql·adb
努力努力再努力wz1 小时前
【Qt入门系列】:QLabel控件详解:从文本显示到图片展示,再到内容布局与伙伴机制
android·开发语言·数据结构·数据库·c++·qt·mysql
Kapaseker2 小时前
用 Kotlin 构建你的第一个 Agent — 开篇
android·kotlin
三雒2 小时前
KMP 实战:Android 开发如何快速统一双端 IM 模块
android·ios·kotlin
码云骑士2 小时前
Android SWT重启问题
android
恋猫de小郭3 小时前
GSY 史上最全跨平台/架构/语言的项目,七大项目召唤「神龙」
android·前端·flutter
shuaiqinke3 小时前
【分享】一刻日记 富文本日记+图文混排+导出分享
android·craiyon
__Witheart__3 小时前
Android RK SDK只编译和烧录kernel(boot.img)
android
黄林晴3 小时前
Compose 键盘焦点别乱写!正确姿势只有这一种
android