AOSP Android14 Launcher3——远程窗口动画关键类SurfaceControl详解

news2025/4/25 2:10:58

在 Launcher3 执行涉及其他应用窗口(即“远程窗口”)的动画时,例如“点击桌面图标启动应用”或“从应用上滑回到桌面”的过渡动画,SurfaceControl 扮演着至关重要的角色。它是实现这些跨进程、高性能、精确定制动画的核心技术。

SurfaceControl在源码中的使用

Launcher3中有几处非常经典的使用SurfaceControl的地方。
在这里插入图片描述

在分屏应用进入到最近任务,或者从最近任务启动应用时,涉及到分屏应用中间的bar条,这个bar条是属于SystemUI进程的,在Launcher中显示就属于远程窗口,因此需要通过SurfaceControl来进行更新操作。
启动分屏应用时bar条由隐藏到最终显示的过程就是通过SurfaceControl控制bar条的透明度来实现的。
源码如下:

    public static ValueAnimator createSplitAuxiliarySurfacesAnimator(
            @Nullable RemoteAnimationTarget[] nonApps, boolean shown,
            @Nullable Consumer<ValueAnimator> animatorHandler) {
        if (nonApps == null || nonApps.length == 0) {
            return null;
        }

        List<SurfaceControl> auxiliarySurfaces = new ArrayList<>();
        for (RemoteAnimationTarget target : nonApps) {
            final SurfaceControl leash = target.leash;
            if (target.windowType == TYPE_DOCK_DIVIDER && leash != null && leash.isValid()) {
                auxiliarySurfaces.add(leash);
            }
        }
        if (auxiliarySurfaces.isEmpty()) {
            return null;
        }

        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        if (animatorHandler == null) {
            // Apply the visibility directly without fade animation.
            for (SurfaceControl leash : auxiliarySurfaces) {
                t.setVisibility(leash, shown);
            }
            t.apply();
            t.close();
            return null;
        }

        ValueAnimator dockFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
        dockFadeAnimator.addUpdateListener(valueAnimator -> {
            float progress = valueAnimator.getAnimatedFraction();
            for (SurfaceControl leash : auxiliarySurfaces) {
                if (leash != null && leash.isValid()) {
                    t.setAlpha(leash, shown ? progress : 1 - progress);
                }
            }
            t.apply();
        });
        dockFadeAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (shown) {
                    for (SurfaceControl leash : auxiliarySurfaces) {
                        t.setLayer(leash, Integer.MAX_VALUE);
                        t.setAlpha(leash, 0);
                        t.show(leash);
                    }
                    t.apply();
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (!shown) {
                    for (SurfaceControl leash : auxiliarySurfaces) {
                        if (leash != null && leash.isValid()) {
                            t.hide(leash);
                        }
                    }
                    t.apply();
                }
                t.close();
            }
        });
        dockFadeAnimator.setDuration(SPLIT_DIVIDER_ANIM_DURATION);
        animatorHandler.accept(dockFadeAnimator);
        return dockFadeAnimator;
    }

下来来详解SurfaceControl在Launcher中的角色以及为什么要使用SurfaceControl

SurfaceControl 的角色:

  1. 窗口/图层的句柄: 在 Android 图形系统中,每个窗口或可视元素最终都对应一个或多个图层 (Layer),这些图层由系统的合成器 (SurfaceFlinger) 负责管理和混合。SurfaceControl 是一个轻量级的句柄 (Handle),它代表了 SurfaceFlinger 中的一个图层(Surface)。你可以把它想象成一个指向屏幕上某个“画板”的遥控器。
  2. 直接操作图层属性: 通过 SurfaceControl,一个有权限的进程(在远程动画场景下,通常是 Launcher 或 SystemUI)可以直接、高效地修改其代表的图层在 SurfaceFlinger 中的各种属性,而无需与创建这个图层的原始应用进程进行复杂的通信或等待其响应。这些属性包括:
    • 几何变换: 位置 (Position)、缩放 (Scale)、旋转 (Rotation) (通常通过设置变换矩阵 Matrix 实现)。
    • 视觉效果: 透明度 (Alpha)、层级 (Z-order)、裁剪区域 (Window Crop)、圆角半径 (Corner Radius)、阴影 (Shadow Radius)、模糊 (Blur) 等。
  3. 跨进程动画的桥梁: 在远程动画中,系统 (WindowManager) 会将参与动画的窗口(例如正在打开的应用窗口、正在关闭的 Launcher 窗口、壁纸窗口)的 SurfaceControl(通常是一个称为 “Leash” 的特殊控制层)打包在 RemoteAnimationTarget 对象中,传递给动画控制器(Launcher)。
  4. 动画执行者 (SurfaceControl.Transaction): Launcher 拿到这些 SurfaceControl 后,不会去修改对应应用的 View 属性,而是创建 SurfaceControl.Transaction 对象。在动画的每一帧:
    • Launcher 计算出每个目标窗口图层应该具有的视觉属性(比如,应用窗口从图标大小放大到全屏,透明度从 0 到 1,裁剪区域从无到有,圆角从大变小)。
    • 使用 Transaction 提供的方法(如 setMatrix(), setAlpha(), setWindowCrop(), setCornerRadius())为每个 SurfaceControl 设置这些目标属性。
    • 最后调用 transaction.apply() 原子性地将这一帧的所有属性变更提交给 SurfaceFlinger
    • SurfaceFlinger 在下一个 VSYNC 信号到来时,根据这些最新的属性来合成并显示屏幕内容,从而驱动了视觉上的动画效果。

为什么在远程动画中使用 SurfaceControl

使用 SurfaceControl 是实现现代 Android 流畅、复杂过渡动画的关键,原因如下:

  1. 高性能 (Performance): 直接在 SurfaceFlinger (系统合成器)层面操作图层属性非常高效,通常能利用硬件加速。这避免了在应用进程内部进行复杂的 View 布局、绘制或属性动画,这些操作可能更耗资源且容易引发卡顿 (Jank)。
  2. 精确同步 (Synchronization): 对于涉及多个应用窗口(跨进程)的过渡动画(如应用启动/关闭、分屏),需要精确地同步它们的动画。通过 SurfaceControl.Transaction,Launcher 可以原子性地更新所有相关图层的属性,确保它们在同一帧内发生变化,实现完美的视觉同步。如果依赖各个应用自己执行动画,几乎不可能做到如此精确的同步。
  3. 强大控制力 (Control): SurfaceControl API 提供了对图层视觉属性的底层、细粒度控制,使得 Launcher 可以实现非常复杂的动画效果,例如从图标到窗口的平滑变形、窗口内容的裁剪、圆角变化等,这些效果很难通过传统的 View 动画或窗口动画(ActivityOptions)实现得如此精细。
  4. 解耦 (Decoupling): 被动画的应用(例如正在启动的应用)不需要主动参与这个由 Launcher 控制的过渡动画。应用只需要正常地将自己的内容绘制到它的 Surface 上即可。Launcher 通过 SurfaceControl 在外部“指挥”SurfaceFlinger 如何变换和展示这个 Surface。这大大降低了应用和系统过渡动画之间的耦合度。
  5. 无缝体验 (Seamlessness): SurfaceControl 使得元素(如图标)看起来能够“无缝地”跨越进程边界变形成为另一个应用的窗口,提供了非常连贯和自然的视觉体验。

总结:

在 Launcher 对远程窗口执行动画的过程中,SurfaceControl 充当了底层图层(Surface)的直接控制器。Launcher 通过它,绕开了应用进程,直接与系统合成器 SurfaceFlinger 交互,以高性能、精确同步的方式驱动应用窗口的几何变换和视觉效果,从而实现了流畅、复杂且跨进程的过渡动画。这是现代 Android 系统动画(尤其是 Quickstep 手势动画)的核心技术基础。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统学习----概述与目录结构

linux 是一个开源、免费的操作系统&#xff0c;其稳定性、安全性、处理多并发已经得到业界的认可&#xff0c;目前很多企业级的项目 (c/c/php/python/java/go)都会部署到 Linux/unix 系统上。 一、虚拟机系统操作 1.网络连接的三种方式&#xff08;桥接模式、nat模式、主机模…

虚拟列表技术深度解析:原理、实现与性能优化实战

虚拟列表技术深度解析&#xff1a;原理、实现与性能优化实战 引言 在当今数据驱动的互联网应用中&#xff0c;长列表渲染已成为前端开发的核心挑战。传统的一次性全量渲染方式在数据量超过千条时&#xff0c;往往导致页面卡顿、内存飙升等问题。虚拟列表&#xff08;Virtual L…

服务器简介(含硬件外观接口介绍)

服务器&#xff08;Server&#xff09;是指提供资源、服务、数据或应用程序的计算机系统或设备。它通常比普通的个人计算机更强大、更可靠&#xff0c;能够长时间无间断运行&#xff0c;支持多个用户或客户端的请求。简单来说&#xff0c;服务器就是专门用来存储、管理和提供数…

c++下的onnx推理

参考代码&#xff1a;https://github.com/itsnine/yolov5-onnxruntime 参考链接&#xff1a;https://blog.csdn.net/magic_ll/article/details/125517798 1.下载onnx 官网&#xff1a;https://github.com/microsoft/onnxruntime/releases/tag/v1.21.0 2.下载代码 https://g…

TCP三次握手与四次挥手面试回答版本

面试官&#xff1a;说一下TCP三次握手的过程 参考面试回答&#xff1a; 在第一次握手的时候、客户端会随机生成初始化序号、放到TCP报文头部的序号字段中、同时把SYN标志设置为1 这样就表示SYN报文&#xff08;这里是请求报文&#xff09;。客户端将报文放入 TCP 报文首部的序…

0101基础知识-区块链-web3

文章目录 1 web3学习路线2 区块链简史2.1 区块链2.2 公共账本2.3 区块链的设计哲学2.3.1 去中心化2.3.2 共识2.3.2.1 上链2.3.2.2 共识算法 3 web3面向资产的互联网3.1 安全性和去中心化的权衡 4 智能合约4.1 以太坊智能合约4.2 去中心化应用 5 小结结语 1 web3学习路线 参考下…

工作纪实_63-Mac电脑使用brew安装软件

最近在接触kafka&#xff0c;想着在自己的电脑安装一套环境&#xff0c;docker也能行&#xff0c;但是还是想装一些原生的软件试试看&#xff0c;因此便想着整理一下brew的命令&#xff0c;这命令确实是方便&#xff0c;不需要下载tar包乱八七糟的东西&#xff0c;一键安装 bre…

Cadence学习笔记之---库元件制作、元件放置

目录 01 | 引 言 02 | 环境描述 03 | 工具介绍 04 | 无源器件的制作 05 | IC芯片制作 06 | 放置元件 07 | 结 语 01 | 引 言 在上一篇小记中&#xff0c;讲述使用Cadence创建原理图工程和元件库&#xff1b; 本篇小记主要讲述如何制作常用的库元件&#xff0c;如电阻、…

服务器如何修复SSL证书错误?

修复服务器上的SSL证书错误需要根据具体错误类型逐步排查和解决。以下是常见的步骤和解决方案&#xff1a; --- ### **1. 确认错误类型** 首先检查浏览器或工具&#xff08;如OpenSSL&#xff09;报错的具体信息&#xff0c;常见错误包括&#xff1a; - **证书过期**&#xf…

图解Mysql原理:深入理解事务的特性以及它的实现机制

前言 大家好&#xff0c;我是程序蛇玩编程。 Mysql中事务大家不陌生吧&#xff0c;事务就是要保证一组数据库操作&#xff0c;要么全部成功&#xff0c;要么全部失败。那它具有哪些特性&#xff0c;如何实现的呢?接着往下看。 正文 事务的特性: 事务的基本特性主要为四种…

Linux[指令与权限]

Linux指令与权限 Linux环境中,打包文件有多种 tar (打包/解包) 指令 tar -czvf 文件要打包到的位置 文件(打包并压缩到) tar -xzvf 文件(在当前目录下解压) tar选项 -c创建压缩文件 -z使用gzip属性压缩 -v展现压缩过程 -f后面使用新建文档名 -x不要新建,解压 -C 文件…

MySQL 的锁,表级锁是哪一层的锁?行锁是哪一层的锁?

MySQL 的锁层级与类型 在 MySQL 中&#xff0c;锁的层级和实现与存储引擎密切相关。 1. 表级锁&#xff08;Table-Level Locks&#xff09; &#xff08;1&#xff09;存储引擎层的表级锁 实现层级&#xff1a;存储引擎层&#xff08;如 MyISAM、InnoDB&#xff09;。特点&a…

windows docker desktop 无法访问容器端口映射

为什么使用docker desktop访问映射的端口失败&#xff0c;而其端口对应的服务是正常的&#xff1f; 常见问题&#xff0c;容器的防火墙没有关闭&#xff01;&#xff01;&#xff01; 以centos7为例&#xff0c;默认情况下防火墙处于开启状态&#xff1a; 这下访问就OK了

OpenRAN 6G网络:架构、用例和开放问题

英文标题&#xff1a; Open RAN for 6G Networks: Architecture, Use Cases and Open Issues 作者信息 Bharat Agarwal&#xff1a;2016年毕业于Galgotias University&#xff0c;获得电气与电子工程学士学位&#xff1b;2023年在爱尔兰都柏林城市大学获得电子工程博士学位。2…

《TCP/IP详解 卷1:协议》之第四、五章:ARP RARP

目录 一、ARP && RARP 报文结构 1、ARP请求报文示例 2、ARP响应报文示例 3、RARP请求报文示例 4、RARP响应报文示例 5、关于 padding 6、免费ARP 二、tcpdump 的使用 1、基本语法 2、常用选项 3、常用过滤条件 三、arp 命令的使用 1、基本语法 2、常用选…

实战华为1:1方式1 to 1 VLAN映射

本文摘自笔者于2024年出版&#xff0c;并得到广泛读者认可&#xff0c;已多次重印的《华为HCIP-Datacom路由交换学习指南》。 华为设备的1 to 1 VLAN映射有1:1和N :1两种方式。1:1方式是将指定的一个用户私网VLAN标签映射为一个公网VLAN标签&#xff0c;是一种一对一的映射关系…

NLP 梳理03 — 停用词删除和规范化

一、说明 前文我们介绍了标点符号删除、文本的大小写统一&#xff0c;本文介绍英文文章的另一些删除内容&#xff0c;停用词删除。还有规范化处理。 二、什么是停用词&#xff0c;为什么删除它们&#xff1f; 2.1 停用词的定义 停用词是语言中的常用词&#xff0c;通常语义…

使用若依二次开发商城系统-1:搭建若依运行环境

前言 若依框架有很多版本&#xff0c;这里使用的是springboot3vue3这样的一个前后端分离的版本。 一.操作步骤 1 下载springboot3版本的后端代码 后端springboot3的代码路径&#xff0c;https://gitee.com/y_project/RuoYi-Vue 需要注意我们要的是springboot3分支。 先用g…

HarmonyOS-ArkUI: 组件内转场(transition)

什么是组件内转场 组件内转场指的是组件在触发转场的时机所具备的动画效果。转场的时机指的是,组件元素发生变化的时候,具体为: 组件被添加组件被删除组件可见性发生变化-Visibility这些场景有时候单纯的让其消失,出现,平移有时候视觉效果会比较突兀。我们可以利用组件内…

MVVM框架详解:原理、实现与框架对比

文章目录 1. 引言2. MVVM的基本概念3. MVVM的原理与实现3.1 数据绑定原理3.2 命令模式实现 4. MVVM的优势与局限性4.1 优势4.2 局限性 5. 常见MVVM框架对比5.1 MVVM Light5.2 Prism5.3 Caliburn.Micro5.4 MvvmCross5.5 ReactiveUI 6. 实际应用示例7. 最佳实践与注意事项7.1 MVV…