任務快照

任務快照是 Android 8.0 中引入的基礎設施,它結合了最近縮圖的螢幕截圖以及視窗管理器中保存的表面。最近的縮圖代表「最近」視圖中任務的最後狀態。

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

建築學

「最近的縮圖」和「已儲存的表面」這兩個概念與任務快照統一。當任務進入背景時,視窗管理器會將該任務的螢幕截圖放入 GraphicBuffer 中。只要任務的top Activity的應用程式還停留在記憶體中,這個GraphicBuffer就會保留在記憶體中。現在,當相同的 Activity 再次置於前台時,視窗管理器將建立起始視窗 (TaskSnapshotSurface),並附加 GraphicBuffer,而不將任何記憶體複製到起始視窗的緩衝區佇列。一旦活動繪製了第一幀,任務快照啟動視窗就會像常規的啟動畫面一樣平滑地淡出。

相同的 GraphicBuffer 也透過 Binder 發送到 SystemUI,用於在「最近」視圖中繪製任務的預覽狀態。由於這只是對緩衝區的引用,因此透過綁定器發送它會消耗很少的資源。當GraphicBuffer到達SystemUI時,它被包裝成硬體位圖,然後繪製到螢幕上,而不需要任何記憶體上傳到圖形記憶體。

好處

這種新架構有三個主要優點:

  • 如果任務快照用作啟動窗口,則快照和真實內容之間會出現很好的交叉淡入淡出效果。
  • 當在SystemUI中繪製任務快照時,無需任何複製即可完成。以前,必須將位圖複製到 Ashmem,然後複製到圖形記憶體中。由於該方法將快照直接儲存在顯存中,因此不需要複製。
  • 您在「最近」中看到的狀態始終與您重新開啟應用程式時首先看到的狀態相符。在這裡使用相同的緩衝區也可以節省大量記憶體。這就是為什麼「最近」現在能夠以全解析度顯示這些影像。此前,為了節省內存,採樣率降低了 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/+/main/services/core/java/com/android/server/wm/