【Android14 ShellTransitions】(四)Transition收集动画参与者

在这里插入图片描述

这一节的内容在WMCore中,现在Transition已经走到COLLECTING状态了,并且可以收集动画参与者了。

那么Transition是在什么时候去收集动画参与者?回到我们最初的ActivityStarter.startActivityUnchecked:

在这里插入图片描述

在调用了TransitionController.createAndStartCollecting后,紧接着就是调用了TransitionController.collect。

在这里插入图片描述

这里看到TransitionController里面首先是判断了一下成员变量mCollectingTransition是否为空,如果不为空,才能将传参WindowContainer收集到该Transition中。

接下来我们重点分析Transition.collect,这里感觉不按照代码顺序分析似乎更有条理一点。

1 Transition.collect第1部分

在这里插入图片描述

1)、如果当前Transition的mState小于STATE_COLLECTING,那么就会异常。

2)、如果当前Transition的mState不是STATE_COLLECTING或者STATE_STARTED,那么就会返回。

这里说明了,只有处于STATE_COLLECTING或者STATE_STARTED的Transition才能收集动画参与者,太早或者太晚都不行。

2 Transition.collect第2部分

在这里插入图片描述

首先看这里needSync的逻辑。

如果,当前正在被收集的WindowContainer不是一个WallpaperWindowToken,

或者,当前参与者中不包含该WindowContainer所在的DisplayContent,

并且,该WindowContainer没有被瞬态隐藏(被Recents遮挡),

那么needSync就为true。

needSync为true,那么继续调用BLASTSyncEngine.addToSycnSet方法:

在这里插入图片描述

很简单,根据传入的Transition的ID找到对应的SyncGroup对象,然后继续调用SyncGroup.addToSync方法:

在这里插入图片描述

该方法内容主要是:

1)、如果当前WindowContainer通过getSyncGroup拿到的SyncGroup为空,说明当前WindowContainer还没有绑定一个SyncGroup,那么就将该WindowContainer添加到SyncGroup.mRootMembers中,并且通过WindowContainer.setSyncGroup方法,将WindowContainer的成员变量mSyncGroup设置为当前SyncGroup,完成绑定。

2)、调用WindowContainer.prepareSync方法。

关于这个prepareSync的逻辑,同样在我们之前分析BLASTSyncEngine的那篇文章中也比较系统的介绍过,因此这里简单再回顾一下。

首先是WindowContainer.prepare方法:

在这里插入图片描述

比较简单,调用子WindowContainer的prepareSync方法,然后将自身的mSyncState设置为SYNC_STATE_READY。

mSyncState有三种状态:

在这里插入图片描述

  • SYNC_STATE_NONE,没有参与到一次同步(或Transition)中。
  • SYNC_STATE_WAITING_FOR_DRAW,等待自身绘制完成。
  • SYNC_STATE_READY,当前WindowContainer已经就绪,但是其子容器可能没有就绪。

一般来说,动画都伴随着界面的改变,比如我们从Launcher启动Contacts,Contacts是一个从无到有的过程,那么动画就需要等待Contacts的窗口绘制完成后才能进行。

因此再看重写了prepareSync方法的WindowState.prepareSync方法的内容:

在这里插入图片描述

重点其实就是这一句,将WindowState的mSyncState置为SYNC_STATE_WAITING_FOR_DRAW。

即对于非WindowState的WindowContainer,比如Task,ActivityRecord,它们在界面发生改变的时候是不需要重绘的,因此它们在prepareSync的时候就可以将mState设置为SYNC_STATE_READY。同理,判断一个Task或者一个ActivityRecord是否就绪,看的主要是它里面的WindowState是否就绪了。

而对于WindowState,在界面发生改变的时候,由于要重绘,并且重绘需要时间,因此WindowState在被添加到动画参与者集合的时候,会先被设置为SYNC_STATE_WAITING_FOR_DRAW。等到绘制完成,为该WindowState调用finishDrawing的时候,它的mSyncState会被设置为SYNC_STATE_READY,表示该窗口已经就绪,可以进行动画。

3 Transition.collect第3部分

在这里插入图片描述

接着看Transition的成员变量mParticipants:

在这里插入图片描述

是一个ArraySet类型的成员变量,看方法最后,是将参与当前Transition的WindowContainer添加进来了,那它的作用和SyncGroup的mRootMembers类似。

从第一部分关于needSync的分析看到,向SyncGroup.mRootMembers添加参与者的条件要比向Transition.mParticipants的条件苛刻一点,因为这个区别,这两个参与者集合中的内容可能不是完全相同的。

4 Transition.collect第4部分

在这里插入图片描述

最后我们再来看一下关于ChangeInfo的这部分。

4.1 例子1 —— 新启动ActivityRecord

还以我们之前分析的从Launcher启动Contacts的流程来,那么在这个时间点,只创建了一个ActivityRecord对象,它的Task还没创建,那么通过Transition.getAnimatableParent获取的WindowContainer自然也就是null了,因此标黄的第一段逻辑就不走了,直接看第二段逻辑。

首先看下Transition.mChanges的定义:

在这里插入图片描述

一个包含了WindowContainer和ChangeInfo键值对的map。

这是我们第一次尝试将当前WindowContainer添加到动画参与者中,因此从Transition.mChanges中肯定是没有当前WindowContainer的,因此这里就会根据该WindowContainer创建一个ChangeInfo对象,并且将这两个对象组成的键值对保存到Transition.mChanges中。

ChangeInfo的构造方法为:

在这里插入图片描述

用来保存改变开始前的WindowContainer的一些信息,大概是这样的用法:

1)、在收集阶段,将基于WindowContainer的当前信息创建一个ChangeInfo,ChangeInfo里保存了我们对WindowContainer感兴趣的特定信息。

2)、发生一些改变。

3)、改变完成后,具体是在Transition.onTransactionReady的时候,拿第一步创建ChangeInfo和现在这个时候的WindowContainer的信息进行对比,从而得知当前WindowContainer在这个过程中发生了哪些变化。

4.2 例子2 —— App切换

在第一个例子中,我们看到由于此时是ActivityRecord刚刚创建的时候,因此ActivityRecord的父容器为空,所以这里仅仅为正在收集的这个ActivityRecord创建了一个ChangeInfo的对象。然而更普遍的情况可能是,不仅为当前正在收集的这个WindowContainer创建了ChangeInfo,还可能会创建更多ChangeInfo对象, 即这段逻辑:

在这里插入图片描述

Transition.getAnimatableParent的定义为:

在这里插入图片描述

如果发生了App的切换,比如从Message界面点击Home回到Launcher,那么就会把Message和Launcher的Task收集起来,走到这里时,传参是Task类型的WindowContainer:

1)、首先Task通过getParent获取到父WindowContainer,即TaskDisplayArea。

2)、TaskDisplayArea复写了WindowContainer.canCreateRemoteAnimationTarget方法:

在这里插入图片描述

返回的是true,那么通过Transition.getAnimatableParent返回了TaskDisplayArea。

3)、最终会为TaskDisplayArea创建一个ChangeInfo对象,添加到Transition.mChanges中。

同理为TaskDisplayArea调用Transition.getAnimatableParent方法,获取到的则是DisplayContent,也会为DisplayContent创建一个ChangeInfo对象添加到Transition.mChanges中。

那么除了为Task创建ChangeInfo之外,这里还会为TaskDisplayArea以及DisplayContent创建ChangeInfo,并且加入到Transition.mChanges中。

最后再来对比一下SyncGroup.mRootMembers、Transition.mParticipants以及Transition.mChangs:

1)、Transition.mParticipants,保存的就是正在收集的那个WindowContainer。

2)、SyncGroup.mRootMembers,由于一些条件限制,保存的WindowContainer比Transition.mParticipants要少一点。

3)、Transition.mChangs,不仅保存了正在收集的那个WindowContainer对应的ChangeInfo对象,还可能保存了它的父WindowContainer对应的ChangeInfo对象。

5 其它collect的情况

看下Transition.collect都在哪些地方调用了:

在这里插入图片描述

并且它也会被TransitionController.collect调用,而TransitionController.collect被调用的地方同样也很多:

在这里插入图片描述

场景太多就不一一分析了,其实万变不离其宗,需要在什么节点把WindowContainer收集进来再去调用Transition.collect就行了,就像之前把ActivityRecord添加到openingApps和closingApps那样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/651066.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vb.net打开CAD指指定路径文件

首先打开vsto,创建窗体,添加一个按钮,双击按钮录入代码: Public Class Form1Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.ClickDim cad As Objectcad CreateObject("autocad.Application")cad…

代码随想录算法训练营第六天| 242.有效的字母异位词 、349. 两个数组的交集 、202. 快乐数、1. 两数之和

242.有效的字母异位词 题目链接: 203.移除链表元素 文档讲解:代码随想录 状态:so easy 思路:使用计数器数组统计字符串中字符出现频率。 题解 public boolean isAnagram(String s, String t) {// 将输入的字符串s转换为字符数组…

World Creator v2.1.0 解锁版安装教程 (GPU三维地形生成软件)

前言 World Creator是一款功能相当强大的地形景观生成器;可以完全根据自己的需求来对地形、景观生成您需要三维模型,内置的大量预设,让您的创建拥有无限的可能性。 一、下载地址 下载链接:http://dygod/ITSource 点击搜索&…

前后端部署笔记

windows版: 如果傻呗公司让用win电脑部署,类似于我们使用笔记本做局域网服务器,社内使用。 1.安装win版的nginx、mysql、node、jdk等 2.nginx开机自启参考Nginx配置及开机自启动(Windows环境)_nginx开机自启动 wind…

学习100个Unity Shader (18) --- 几何着色器(Geometry Shader)

文章目录 概述编写格式举例应用举例(用预制体球的每个顶点画一个立方体)参考 概述 vertex shader --> [geometry shader] --> fragment shader。[]: 可选阶段。输入图元 —> geometry shader —> 其他图元 编写格式 [maxcertexcount(N)] …

源码编译安装LAMP与部署

目录 一、LAMP架构的简述 1.LAMP搭建时各组件安装顺序 二、编译安装Apache httpd服务 1.关闭防火墙,将安装Apache所需软件包传到/opt目录下 2.安装环境依赖包​编辑 3.配置软件模块 4.编译及安装 5.优化配置文件路径,并把httpd服务的可执行程序文…

2024斯佩菈音乐剧暑假训练营 30天创造奇迹培育坚强自信好少年

以声问本,素质教育,融会中西,知行合一。音乐是生活的灵魂,艺术的真正意义在于使人幸福,得到鼓舞和力量。多一把衡量的尺子,就会多出一批好学生。 相对学校语数英等学科教育,孩子心灵成长方面很…

新建gitee项目关联idea中的springboot项目

新建项目关联仓库步骤 以gitee为例新建项目 进入gitee新建项目 新建项目后进入复制项目地址 可以直接拉取本项目然后再这个目录下创建各种功能,我习惯于以下步骤。 下一步再idea新建springboot项目 我使用的是idea2023 选择Manager remote 点击加号 新建一个远…

1+x(Java)中级题库易混淆理论题(二)

冷备份实质就是数据库相关文件的复制 System.in是字节流 Map集合中的key是无序的 protected不能用于修饰类 接口中所有抽象方法默认使用public修饰 DML操作有:INSERT UPDATE DELETE SQL 语句中进行 group by 分组时,可以不写 where 子句 使…

什么是HTTP代理?适用于哪些场景?

HTTP代理是一种网络代理服务器,它主要用于处理HTTP协议的请求和响应。HTTP代理充当客户端(如浏览器)和目标服务器之间的中介,允许客户端通过代理服务器来发送HTTP请求,并接收来自服务器的响应。HTTP代理可以分为正向代…

C语言文件编程

C语言文件编程 第一部分 基本概念 1、Linux文件类型 1.-普通文件:存在于外部存储器中,用于存储普通数据。 1.txt 1.c 1.mp3 1.mp4 2.d目录文件:用于存放目录项,是文件系统管理的重要文件类型。 文件夹 3.p管道文件&#x…

LDRA Testbed(TBrun)软件单元测试_操作指南

系列文章目录 LDRA Testbed软件静态分析_操作指南 LDRA Testbed软件静态分析_自动提取静态分析数据生成文档 LDRA Testbed软件静态分析_Jenkins持续集成_(1)自动进行静态分析的环境搭建 LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果 LDRA Testb…

探索循环逻辑:for逻辑分支与容器遍历的深度剖析

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言:for逻辑与循环体的奥秘 二、for逻辑与循环体的结合使用 1. 函数与循环…

Python计算回归拟合各项指标

0、各项回归指标简介 Relative Root Mean Squared Error(RRMSE):The RRMSE normalizes the Root Mean Squared Error (RMSE) by the mean of observations. It goes from 0 to infinity. The lower the better the prediction performance.T…

电脑不能远程桌面连接不上,电脑无法建立远程桌面连接如何解决?

电脑无法建立远程桌面连接的问题,通常涉及到多个层面的因素,包括但不限于网络设置、系统配置、防火墙设置以及服务状态等。以下是一些专业性的解决方案,以帮助您解决这一问题。 首先,我们需要检查网络连接。远程桌面连接需要稳定的…

Day08:CSS 高级

目标:掌握定位的作用及特点;掌握 CSS 高级技巧 一、定位 作用:灵活的改变盒子在网页中的位置 实现: 1.定位模式:position 2.边偏移:设置盒子的位置 leftrighttopbottom 水平方向偏移:left、…

电子商务网站(网上商店PetShop)

PetShop是一个范例,微软用它来展示.Net企业系统开发的能力。PetShop随着版本的不断更新,至现在基于.Net2.0的PetShop 4.0为止,整个设计逐渐变得成熟而优雅,有很多可以借鉴之处。PetShop是一个小型的项目,系统架构与代码…

【软件设计师】——7.软件工程基础

目录 7.1 软件工程概述 7.2 需求分析 7.3 软件设计 7.4 软件开发方法及模型 7.4.1 软件开发方法 7.4.2 软件开发模型 7.5 软件测试 7.6 软件维护 7.7 软件质量保证 7.7.1 软件质量特性 7.7.2 程序质量评审 7.7.3 设计质量评审 7.8 软件过程改进 7.9 项目管理 7.1 …

【制作100个unity游戏之26】unity2d横版卷轴动作类游13(附带项目源码)

最终效果 系列导航 文章目录 最终效果系列导航前言存储点灯光后处理存储位置信息存储更多数据存储场景信息持久化存储数据引入Unity 的可序列化字典类调用 游戏结束源码完结 前言 欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各…

Appium系列(2)元素定位工具appium-inspector

背景 如实现移动端自动化,依赖任何工具时,都需要针对于页面中的元素进行识别,通过识别到指定的元素,对元素进行事件操作。 识别元素的工具为appium官网提供的appium-inspector。 appium-inspector下载地址 我这里是mac电脑需要下…