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

相关推荐
YSoup10 小时前
Android Stuidio中下载TRAE插件依赖的JCEF后打不开
android
2401_8949155311 小时前
Geo搜索优化排名源码部署搭建全流程详解
android·开发语言·flask·php·精选
星释11 小时前
鸿蒙智能体开发实战:34.鸿蒙壁纸大师 - 提示词工程与优化
android·华为·harmonyos·鸿蒙
blanks202012 小时前
android 编译问题记录
android
bobuddy13 小时前
平台总线(platform bus)
android
plainGeekDev13 小时前
libs 目录 → Gradle 依赖管理
android·java·kotlin
帅次14 小时前
Android 高级工程师面试:Flutter Widget 体系 近1年高频追问 20 题
android·flutter·面试·element·widget·setstate·renderobject
帅次14 小时前
Android 高级工程师面试:Jetpack 核心 近1年高频追问 20 题
android·面试·协程·jetpack·stateflow·lifecycle
爱笑鱼15 小时前
Handler(四):Handler 卡顿怎么定位?从 Slow delivery 到 Slow dispatch
android
九皇叔叔15 小时前
RHEL9.8 配置本地镜像仓库
android·java·缓存