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

相关推荐
漏刻有时7 小时前
PHP GeoJSON转PNG地图渲染程序开发笔记、源码解读、问题复盘与整改方案
android·笔记·php
-SOLO-8 小时前
解决VMware 显示比例被重置的问题
android
alexhilton8 小时前
探究Android Views、Flutter和Compose如何渲染你的UI
android·kotlin·android jetpack
Lesile11 小时前
Android:Hilt框架入门 · 在ViewUI和ComposeUI下的应用
android·android jetpack
用户4238162290711 小时前
Android 16 WebView 页面顶部挖孔/通知栏不能显示UI问题排查
android
weixin_7275356212 小时前
Loop 已死,Graph 新生:AI 工作流的范式革命
android·人工智能·rxjava
严同学正在努力13 小时前
从备份到恢复:我用 30 分钟恢复了误删的核心业务表
android·java·数据库·ai
梦想三三13 小时前
LangChain Output Parser 实战:从字符串到结构化数据的完整指南
android·服务器·langchain·github·uv
爱笑鱼16 小时前
Binder(八):远端进程死了,BinderProxy 为什么还能收到通知?
android
Android-Flutter16 小时前
Kotlin 冷流与热流详解
android·kotlin