AOSP Android14 Launcher3——遠程窗口動畫關鍵類SurfaceControl詳解

在 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() {@Overridepublic 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();}}@Overridepublic 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.pswp.cn/pingmian/77649.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77649.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77649.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

超詳細實現單鏈表的基礎增刪改查——基于C語言實現

文章目錄 1、鏈表的概念與分類1.1 鏈表的概念1.2 鏈表的分類 2、單鏈表的結構和定義2.1 單鏈表的結構2.2 單鏈表的定義 3、單鏈表的實現3.1 創建新節點3.2 頭插和尾插的實現3.3 頭刪和尾刪的實現3.4 鏈表的查找3.5 指定位置之前和之后插入數據3.6 刪除指定位置的數據和刪除指定…

17.整體代碼講解

從入門AI到手寫Transformer-17.整體代碼講解 17.整體代碼講解代碼 整理自視頻 老袁不說話 。 17.整體代碼講解 代碼 import collectionsimport math import torch from torch import nn import os import time import numpy as np from matplotlib import pyplot as plt fro…

前端性能優化:所有權轉移

前端性能優化&#xff1a;所有權轉移 在學習rust過程中&#xff0c;學到了所有權概念&#xff0c;于是便聯想到了前端&#xff0c;前端是否有相關內容&#xff0c;于是進行了一些實驗&#xff0c;并整理了這些內容。 所有權轉移&#xff08;Transfer of Ownership&#xff09;…

Missashe考研日記-day23

Missashe考研日記-day23 0 寫在前面 博主前幾天有事回家去了&#xff0c;斷更幾天了不好意思&#xff0c;就當回家休息一下調整一下狀態了&#xff0c;今天接著開始更新。雖然每天的博客寫的內容不算多&#xff0c;但其實還是挺費時間的&#xff0c;比如這篇就花了我40多分鐘…

Docker 中將文件映射到 Linux 宿主機

在 Docker 中&#xff0c;有多種方式可以將文件映射到 Linux 宿主機&#xff0c;以下是常見的幾種方法&#xff1a; 使用-v參數? 基本語法&#xff1a;docker run -v [宿主機文件路徑]:[容器內文件路徑] 容器名稱? 示例&#xff1a;docker run -it -v /home/user/myfile.txt:…

HarmonyOS-ArkUI-動畫分類簡介

本文的目的是,了解一下HarmonyOS動畫體系中的分類。有個大致的了解即可。 動效與動畫簡介 動畫,是客戶端提升界面交互用戶體驗的一個重要的方式。可以使應用程序更加生動靈越,提高用戶體驗。 HarmonyOS對于界面的交互方面,圍繞回歸本源的設計理念,打造自然,流暢品質一提…

C++如何處理多線程環境下的異常?如何確保資源在異常情況下也能正確釋放

多線程編程的基本概念與挑戰 多線程編程的核心思想是將程序的執行劃分為多個并行運行的線程&#xff0c;每個線程可以獨立處理任務&#xff0c;從而充分利用多核處理器的性能優勢。在C中&#xff0c;開發者可以通過std::thread創建線程&#xff0c;并使用同步原語如std::mutex、…

區間選點詳解

步驟 operator< 的作用在 C 中&#xff0c; operator< 是一個運算符重載函數&#xff0c;它定義了如何比較兩個對象的大小。在 std::sort 函數中&#xff0c;它會用到這個比較函數來決定排序的順序。 在 sort 中&#xff0c;默認會使用 < 運算符來比較兩個對象…

前端配置代理解決發送cookie問題

場景&#xff1a; 在開發任務管理系統時&#xff0c;我遇到了一個典型的身份認證問題&#xff1a;??用戶登錄成功后&#xff0c;調獲取當前用戶信息接口卻提示"用戶未登錄"??。系統核心流程如下&#xff1a; ??用戶登錄??&#xff1a;調用 /login 接口&…

8.1 線性變換的思想

一、線性變換的概念 當一個矩陣 A A A 乘一個向量 v \boldsymbol v v 時&#xff0c;它將 v \boldsymbol v v “變換” 成另一個向量 A v A\boldsymbol v Av. 輸入 v \boldsymbol v v&#xff0c;輸出 T ( v ) A v T(\boldsymbol v)A\boldsymbol v T(v)Av. 變換 T T T…

【java實現+4種變體完整例子】排序算法中【冒泡排序】的詳細解析,包含基礎實現、常見變體的完整代碼示例,以及各變體的對比表格

以下是冒泡排序的詳細解析&#xff0c;包含基礎實現、常見變體的完整代碼示例&#xff0c;以及各變體的對比表格&#xff1a; 一、冒泡排序基礎實現 原理 通過重復遍歷數組&#xff0c;比較相鄰元素并交換逆序對&#xff0c;逐步將最大值“冒泡”到數組末尾。 代碼示例 pu…

系統架構設計(二):基于架構的軟件設計方法ABSD

“基于架構的軟件設計方法”&#xff08;Architecture-Based Software Design, ABSD&#xff09;是一種通過從軟件架構層面出發指導詳細設計的系統化方法。它旨在橋接架構設計與詳細設計之間的鴻溝&#xff0c;確保系統的高層結構能夠有效指導后續開發。 ABSD 的核心思想 ABS…

Office文件內容提取 | 獲取Word文件內容 |Javascript提取PDF文字內容 |PPT文檔文字內容提取

關于Office系列文件文字內容的提取 本文主要通過接口的方式獲取Office文件和PDF、OFD文件的文字內容。適用于需要獲取Word、OFD、PDF、PPT等文件內容的提取實現。例如在線文字統計以及論文文字內容的提取。 一、提取Word及WPS文檔的文字內容。 支持以下文件格式&#xff1a; …

Cesium學習筆記——dem/tif地形的分塊與加載

前言 在Cesium的學習中&#xff0c;學會讀文檔十分重要&#xff01;&#xff01;&#xff01;在這里附上Cesium中英文文檔1.117。 在Cesium項目中&#xff0c;在平坦坦地球中加入三維地形不僅可以增強真實感與可視化效果&#xff0c;還可以??提升用戶體驗與交互性&#xff0c…

Spring Boot 斷點續傳實戰:大文件上傳不再怕網絡中斷

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 一、痛點與挑戰 在網絡傳輸大文件&#xff08;如視頻、數據集、設計稿&#xff09;時&#xff0c;常面臨&#xff1a; 上傳中途網絡中斷需重新開始服務器內…

數碼管LED顯示屏矩陣驅動技術詳解

1. 矩陣驅動原理 矩陣驅動是LED顯示屏常用的一種高效驅動方式&#xff0c;利用COM&#xff08;Common&#xff0c;公共端&#xff09;和SEG&#xff08;Segment&#xff0c;段選&#xff09;線的交叉點控制單個LED的亮滅。相比直接驅動&#xff0c;矩陣驅動可以顯著減少所需I/…

【上位機——MFC】菜單類與工具欄

菜單類 CMenu&#xff0c;封裝了關于菜單的各種操作成員函數&#xff0c;另外還封裝了一個非常重要的成員變量m_hMenu(菜單句柄) 菜單使用 添加菜單資源加載菜單 工具欄相關類 CToolBarCtrl-》父類是CWnd&#xff0c;封裝了關于工具欄控件的各種操作。 CToolBar-》父類是CC…

liunx中常用操作

查看或修改linux本地mysql端口 cat /etc/my.cnf 如果沒有port可以添加&#xff0c;有可以修改 查看本地端口占用情況 bash netstat -nlt | grep 3307 HADOOP集群 hdfs啟動與停止 # 一鍵啟動hdfs集群 start-dfs.sh # 一鍵關閉hdfs集群 stop-dfs.sh #除了一鍵啟停外&#x…

衡石chatbi如何通過 iframe 集成

iframe 集成方式是最簡單的一種&#xff0c;您只需要在您的 HTML 文件中&#xff08;或 Vue/React 組件中&#xff09;添加一個 iframe 元素&#xff0c;并設置其 src 屬性為 AI 助手的 URL。 <iframesrc"https://develop.hengshi.org/copilot"width"100%&q…

Java集合框架深度解析:HashMap、HashSet、TreeMap、TreeSet與哈希表原理詳解

一、核心數據結構總覽 1. 核心類繼承體系 graph TDMap接口 --> HashMapMap接口 --> TreeMapSet接口 --> HashSetSet接口 --> TreeSetHashMap --> LinkedHashMapHashSet --> LinkedHashSetTreeMap --> NavigableMapTreeSet --> NavigableSet 2. 核心特…