任務快照

Task Snapshots是 Android 8.0 中引入的基礎架構,它結合了最近縮略圖的屏幕截圖以及來自 Window Manager 的Saved Surfaces 。最近的縮略圖表示最近視圖中任務的最後狀態。

當活動進入停止狀態時,只要該活動位於任務的頂部,窗口管理器就不會破壞活動的表面。如果必須再次顯示此活動,則窗口管理器能夠啟動動畫,而無需等待活動完成其第一幀的繪製,因為它能夠使用此保存的表面。

建築學

最近的縮略圖和保存的表面這兩個概念與任務快照統一。當一個任務進入後台時,窗口管理器將該任務的屏幕截圖放入一個 GraphicBuffer 中。只要任務的topactivity的應用程序留在內存中,這個GraphicBuffer就會被保留在內存中。現在,當同樣的activity再次被帶到前面時,窗口管理器將創建一個啟動窗口(TaskSnapshotSurface),並附加GraphicBuffer而不復制任何內存到啟動窗口的緩衝隊列中。一旦 Activity 繪製了它的第一幀,Task Snapshot 開始窗口就會像常規啟動屏幕一樣平滑地淡出。

相同的 GraphicBuffer 也通過 Binder 發送到 SystemUI,用於在最近視圖中繪製任務的預覽狀態。由於這只是對緩衝區的引用,因此通過 binder 發送它會消耗很少的資源。當 GraphicBuffer 到達 SystemUI 時,它會被包裝到硬件 Bitmap 中,然後繪製到屏幕上,而無需將任何內存上傳到圖形內存。

好處

這種新架構有三個主要好處:

  • 如果將任務快照用作起始窗口,則快照和真實內容之間會有很好的交叉淡入淡出。
  • 在 SystemUI 中繪製任務快照時,無需任何復制即可完成。以前必須將位圖複製到 Ashmem,然後再复製到圖形內存中。由於此方法將快照直接存儲在圖形內存中,因此不需要復制。
  • 您在“最近”中看到的狀態始終與您在重新打開應用程序時首先看到的狀態相匹配。在這裡使用相同的緩衝區也可以節省大量內存。這就是Recents 現在能夠以全分辨率顯示這些圖像的原因。以前,它被降低了 64% 以節省內存。

執行

此功能完全存在於 Android 平台中。無需集成,不支持自定義。但是,設備製造商可能會完全禁用任務快照功能。

要禁用此功能,請修改此功能:

frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java#215

請注意,如果禁用該功能,“最近”視圖將不會顯示任何縮略圖。

高分辨率和低分辨率快照

任務快照以兩種規模寫入磁盤。從磁盤恢復任務快照時,首先讀取低分辨率快照,然後替換為高分辨率快照。這種優化改善了圖像加載時間。否則,從磁盤讀取快照文件時可能會稍有延遲,並且在圖像可用之前,用戶會看到一張空白的任務卡。您可以通過設置config_highResTaskSnapshotScaleconfig_lowResTaskSnapshotScale在設備覆蓋配置文件overlay/frameworks/base/core/res/res/values/config.xml中配置比例。默認情況下,它們分別設置為 1.0 和 0.5。通過將config_lowResTaskSnapshotScale設置為 0.0 來禁用低分辨率快照。

示例和來源

在以下位置的 TaskSnapshot* 文件中找到此功能的其餘代碼:

frameworks/base/+/master/services/core/java/com/android/server/wm/