UI 資源浪費偵測

Android 會從應用程式產生影格並將其顯示在螢幕上以呈現 UI。如果應用程式的 UI 顯示速度緩慢,系統會強制略過影格。當這種情況發生時,使用者會在螢幕上看到週期性閃爍的情形,稱為資源浪費

發生資源浪費時,通常是因為 UI 執行緒上的部分減速或封鎖非同步呼叫 (在大多應用程式中,是主要執行緒) 所致。您可以透過系統追蹤記錄找出問題。

在 Android 12 及以上版本上偵測資源浪費

對於搭載 Android 12 (API 級別 31) 或以上版本的裝置,CPU 分析器的「Display」(顯示) 窗格下方的「Janky frames」(卡頓的影格) 軌跡會顯示已擷取的追蹤記錄。

如何偵測資源浪費:

  1. 在 Android Studio 中,依序選取「View」(檢視) >「Tool Windows」(工具視窗) >「Profiler」(分析器),或按一下工具列中的「Profile」(設定檔) 圖示

    如果畫面顯示「Select Deployment Target」(選取部署目標) 對話方塊,請選擇要用來部署應用程式的裝置,以便進行剖析。如果您已透過 USB 連線裝置,但清單中未列出該裝置,請確認您已啟用 USB 偵錯

  2. 按一下 CPU 時間軸中任一處,即可開啟 CPU 分析器。

  3. 在 CPU 分析器的設定選單中,選取「System Trace」(系統追蹤),然後按一下「Record」(記錄)。與應用程式互動完畢後,按一下「Stop」(停止)

  4. 「Display」(顯示) 底下應該會顯示「Janky frames」(卡頓影格) 軌跡。根據預設,分析器只會將卡頓的影格列為調查的候選項目。在每個卡頓影格中,紅色部分會醒目顯示影格超過轉譯期限的時間區段。「Janky frames」(卡頓影格) 軌跡的螢幕截圖

  5. 找到某個卡頓影格後,在上面按一下;或者,您也可以按下「M」來調整縮放,將焦點移至所選影格上。這些執行緒中的相關事件會醒目顯示:主執行緒、RenderThreadGPU 完成數分析器的螢幕截圖,顯示「Janky frames」(卡頓影格) 和主要執行緒

  6. 您可以選擇查看所有影格或轉譯時間的詳細資訊,只要分別勾選「All Frames」(所有影格) 和「Lifecycle」(生命週期) 核取方塊即可。 與上圖類似的分析器螢幕截圖,但「All Frames」(所有影格) 和「Lifecycle」(生命週期) 核取方塊為勾選狀態

在 Android 11 上偵測資源浪費

對於使用 Android 11 (API 級別 30) 的裝置,CPU 分析器的「Frame Lifecycle」(影格生命週期) 區段會顯示已擷取的追蹤記錄。

透過不同軌跡呈現「Frame Lifecycle」(影格生命週期)

「Frame Lifecycle」(影格生命週期) 區段包含圖層名稱和四個軌跡。每個軌跡都代表影格轉譯管線中的一個階段。「Frame Lifecycle」(影格生命週期) 元素如下所示:

  1. 「Frame Lifecycle」(影格生命週期) (層級名稱):區段標題包含層級名稱 (用括號括起來)。層級是單一的構成單位
  2. 「Application」(應用程式):此軌跡顯示將緩衝區被應用程式退出佇列及重新排入佇列的時間。這通常會對應至 RenderThread 中的追蹤事件。
  3. 「Wait for GPU」(等待 GPU):這個軌跡會顯示 GPU 擁有緩衝區的時長。此為從緩衝區發送到 GPU 至 GPU 完成其在緩衝區工作的時間。但這並不表示 GPU 在這段期間內只會在這個緩衝區中作業。如要進一步瞭解 GPU 在指定時間範圍內的運作方式,建議您使用 Android GPU 檢查器
  4. 「Composition」(組成):這個軌跡顯示的時間為,從 SurfaceFlinger 鎖定到緩衝區,後將其發送至組成,再從緩衝區發送至螢幕。
  5. 「Frames on Display」(顯示影格數):這個軌跡會顯示影格停留在畫面上的時間長度。

「Frame Lifecycle」(影格生命週期) 區段會說明影格緩衝區如何在轉譯管道的不同階段之間移動。影格會依影格編號進行顏色編碼,方便您更容易追蹤特定的影格。

Android Studio 也會在「All Frames」(所有影格) 分頁中以表格格式顯示追蹤記錄中的所有影格。

「All Frames」(所有影格) 分頁中追蹤的所有影格的表格

「Frame #」(影格數)、「Application」(應用程式)、「Wait for GPU」(等待 GPU)和「Composition」(組成)資料欄分別代表與上述「Frame Lifecycle」(影格生命週期) 區段內軌跡相同的資料。「Frame Duration」(影格持續時間) 資料欄代表從「Application」(應用程式) 開頭到「Frames on Display」(顯示影格數) 開頭的時間。這本質上是端到端顯示影格所需的時間。

您可以按照任何資料欄排序影格表格,以快速找到最短或最長的影格。表格也支援分頁控制選項,可協助您瀏覽數百個影格。

如要在 Android 11 上偵測及調查資源浪費,請按照下列步驟操作:

  1. 「Application」(應用程式) 欄遞減排序「All Frames」(所有影格) 表格,因此最耗時的影格優先顯示。

    應用程式資料欄 (遞減排序)

  2. 查看最長的執行時間,然後選取表格列。這會在左側時間軸檢視畫面中放大所選影格。

    「Frames」(影格) 表格旁的時間軸檢視畫面

  3. 「Frame Lifecycle」(影格生命週期) 和「Threads」(執行緒) 區段中尋找相關的執行緒。

    「Frame Lifecycle」(影格生命週期) 和「Threads」(執行緒) 區段

在 Android 10 及以下版本上偵測資源浪費

對於使用 Android 10 (API 級別 29) 及以下版本的裝置,相關 OS 圖形管道資訊會顯示在 CPU 分析器系統追蹤記錄上名為「Display」(顯示) 的單一區段中。

顯示 UI 視窗

  • 影格:本節顯示應用程式中的 UI 執行緒和 RenderThread 追蹤記錄事件。超過 16 毫秒的事件會呈紅色,以醒目顯示潛在卡頓影格,因為其已超過顯示 60 個每秒影格數 (fps) 的期限。
  • 「SurfaceFlinger」:本節顯示 SurfaceFlinger 如何處理畫面緩衝區。SurfaceFlinger 是一種系統處理程序,用來傳送要顯示的緩衝。
  • 「VSYNC」:本節顯示 VSYNC,這是同步處理顯示管道的信號。這個軌跡會顯示 VSYNC-app 信號,在應用程式啟動太晚時顯示。原因通常是因為 UI 執行緒處於忙碌狀態。當您使用動畫功能時,螢幕會有可見的閃爍畫面,並在動畫或捲動完成前加上額外輸入延遲時間。由於顯示頻率可能會超過每秒 60 次,或以可變速率顯示,因此這對於查看高刷新率的螢幕尤其重要。
  • BufferQueue:這個部分顯示有多少影格已排入緩衝區,正在等待 SurfaceFlinger 使用。如果是部署至執行 Android 9 (API 級別 28) 或以上版本裝置的應用程式,此軌跡顯示應用程式介面 BufferQueue (01、或 2) 的緩衝區數量。BufferQueue 能協助您瞭解圖片緩衝區在 Android 圖形元件之間移動時的狀態。例如,2 表示應用程式目前處於三重緩衝處理,造成額外的輸入延遲時間。

「Display」(顯示) 部分會提供實用的信號來偵測潛在的資源浪費,例如當 UI 執行緒或 RenderThread 耗時超過 16 ms 時。如要調查導致資源浪費的確切詳細資料,您可以探測「Threads」(執行緒) 部分,其中顯示與 UI 轉譯相關的執行緒。

「Display」(顯示) 下方的「Threads」(執行緒) 區段

在上圖中,「Threads」(執行緒) 區段會顯示 UI 執行緒 (java.com.google.samples.apps.iosched)、RenderThreadGPU completion 執行緒。這些是與 UI 顯示相關的執行緒,可能會導致資源浪費。

如要在 Android 10 或以下版本中偵測資源浪費,請按照下列步驟操作:

  1. 查看「Display」(顯示) 中的「Frames」(影格) 軌跡。紅框是調查的候選項。

    「Display」(顯示) 下方的「Frames」(影格) 區段

  2. 找到可能卡頓的影格時,按下 W 或按住 Control (macOS 為 Command) 並捲動滑鼠滾輪來放大畫面。繼續放大,直到開始在 UI 執行緒和 RenderThread 中看到追蹤事件為止。

    UI 執行緒和 RenderThread 中的追蹤事件

    在上圖中,UI 執行緒呼叫 Choreographer 以協調動畫、檢視版面配置、圖片繪圖及相關程序時,會顯示 Choreographer#doFrameRenderThread 組成並發出對 GPU 的實際繪圖指令時,會顯示 DrawFrames

  3. 如果您看到特別長的追蹤記錄事件,可以進一步縮小,找出導致顯示速度變慢的原因。上圖顯示了 UI 執行緒中的 inflate,這表示應用程式正在耗時加載版面配置。當您放大其中一個 inflate 事件時,您可準確瞭解每個 UI 元件花費的時間,如下圖所示。

    顯示 UI 元件精確時長的選單

瞭解詳情

如要進一步瞭解如何減少資源浪費,請參閱資源浪費的常見來源