Erkennung von UI-Verzögerungen

Android rendert die Benutzeroberfläche, indem ein Frame aus Ihrer App generiert und auf dem Bildschirm angezeigt wird. Wenn die Benutzeroberfläche Ihrer App langsam gerendert wird, wird das System gezwungen, Frames zu überspringen. In diesem Fall nimmt der Nutzer ein wiederkehrendes Flackern auf dem Bildschirm wahr, was als Verzögerung bezeichnet wird.

Eine Verzögerung ist in der Regel auf eine gewisse Verlangsamung oder Blockierung von asynchronen Aufrufen im UI-Thread zurückzuführen. In den meisten Anwendungen ist dies der Hauptthread. Sie können System-Traces verwenden, um zu ermitteln, wo das Problem liegt.

Verzögerungen unter Android 12 und höher erkennen

Auf Geräten mit Android 12 (API-Level 31) oder höher wird ein erfasster Trace im Track Janky Frames im Bereich Display des CPU-Profils angezeigt.

Um eine Verzögerung zu erkennen,

  1. Wählen Sie in Android Studio View > Tool Windows > Profiler aus oder klicken Sie in der Symbolleiste auf Profil .

    Wenn Sie im Dialogfeld Bereitstellungsziel auswählen dazu aufgefordert werden, wählen Sie das Gerät aus, auf dem Ihre Anwendung für die Profilerstellung bereitgestellt werden soll. Wenn Sie ein Gerät über USB verbunden haben, es aber nicht in der Liste sehen, prüfen Sie, ob das USB-Debugging aktiviert ist.

  2. Klicken Sie auf eine beliebige Stelle auf der CPU-Zeitachse, um den CPU-Profiler zu öffnen.

  3. Wählen Sie im CPU-Profiler im Konfigurationsmenü die Option System Trace aus und klicken Sie auf Aufzeichnen. Wenn Sie die Interaktion mit der App abgeschlossen haben, klicken Sie auf Beenden.

  4. Der Track Janky Frames sollte unter Display angezeigt werden. Standardmäßig zeigt Profiler nur langsame Frames als Kandidaten für die Prüfung an. Innerhalb jedes einzelnen Frames hebt der rote Teil die Dauer hervor, die das Rendering-Zeitlimit des Frames überschritten hat. Screenshot des Tracks für Janky-Frames

  5. Wenn Sie einen fehlerhaften Frame gefunden haben, klicken Sie darauf. Optional können Sie M drücken, um den Zoom anzupassen und den Fokus auf den ausgewählten Frame zu legen. Die relevanten Ereignisse sind in diesen Threads hervorgehoben: der Hauptthread, RenderThread und die GPU-Vervollständigung. Screenshot des Profilers, der Janky-Frames und Hauptthreads anzeigt

  6. Optional können Sie alle Frames oder eine Aufschlüsselung der Renderingzeit sehen, indem Sie die Kästchen Alle Frames und Lebenszyklus anklicken. Screenshot des Profilers (siehe oben), aber die Kästchen „Alle Frames“ und „Lebenszyklus“ sind aktiviert.

Verzögerung unter Android 11 erkennen

Auf Geräten mit Android 11 (API-Level 30) wird im CPU-Profiler im Abschnitt Frame-Lebenszyklus ein erfasster Trace angezeigt.

Abschnitt „Frame-Lebenszyklus“ mit verschiedenen Tracks

Der Abschnitt Frame-Lebenszyklus enthält den Ebenennamen und vier Tracks. Jeder Spur stellt eine Phase in der Frame-Rendering-Pipeline dar. Unter Frame-Lebenszyklus finden Sie folgende Elemente:

  1. Frame-Lebenszyklus (Ebenenname): Der Abschnittstitel enthält den Ebenennamen in Klammern. Eine Ebene ist eine einzelne Zusammensetzungseinheit.
  2. Application: Dieser Track zeigt den Zeitraum ab dem Zeitpunkt, zu dem der Zwischenspeicher von der Anwendung aus der Warteschlange entfernt wurde, bis zu dem Zeitpunkt, zu dem er wieder in die Warteschlange eingereiht wurde. Dies entspricht in der Regel den Trace-Ereignissen in RenderThread.
  3. Auf GPU warten: Dieser Track gibt an, wie lange die GPU den Zwischenspeicher gehörte. Dies ist die Zeitspanne zwischen dem Senden des Zwischenspeichers an die GPU und der Verarbeitung des Zwischenspeichers durch die GPU. Dies bedeutet nicht, dass die GPU während dieser Zeit nur mit diesem Zwischenspeicher funktioniert hat. Detaillierte Informationen darüber, womit die GPU in einem bestimmten Zeitraum funktioniert, erhalten Sie mit dem Android GPU Inspector.
  4. Composition: Dieser Track zeigt die Zeit ab dem Zeitpunkt, an dem SurfaceFlinger den Zwischenspeicher anschließt und zur Zusammensetzung sendet, bis zu dem Zeitpunkt, zu dem der Zwischenspeicher an die Anzeige gesendet wird.
  5. Displays auf dem Display: Dieser Track gibt an, wie lange der Frame auf dem Bildschirm zu sehen war.

Im Abschnitt Frame-Lebenszyklus wird gezeigt, wie ein Frame-Zwischenspeicher zwischen verschiedenen Phasen der Rendering-Pipeline verschoben wird. Die Frames sind farblich nach Frame-Nummer gekennzeichnet, um das Tracking eines bestimmten Frames zu vereinfachen.

In Android Studio werden außerdem auf dem Tab Alle Frames alle Frames im Trace in einem Tabellenformat angezeigt.

Eine Tabelle aller Frames im Trace auf der Registerkarte „Alle Frames“

Die Spalten Frame Nr., Anwendung, Auf GPU warten und Komposition stehen für dieselben Daten wie die Tracks im Abschnitt Frame-Lebenszyklus (siehe oben). Die Spalte Frame Duration steht für die Zeit vom Start von Application bis zum Beginn von Frames on Display. Dies ist im Wesentlichen die Zeit, die für das End-to-End-Rendering eines Frames benötigt wird.

Sie können die Frames-Tabelle nach einer beliebigen Spalte sortieren, um schnell den kürzesten oder längsten Frame zu finden. Die Tabelle unterstützt auch Steuerelemente zur Paginierung, mit denen Sie sich durch Hunderte von Frames bewegen können.

So erkennen und untersuchen Sie eine Verzögerung unter Android 11:

  1. Sortieren Sie die Tabelle All Frames (Alle Frames) in absteigender Reihenfolge nach der Spalte Application, sodass die am längsten dauernden Frames zuerst angezeigt werden.

    Anwendungsspalte in absteigender Reihenfolge sortiert

  2. Suchen Sie die Frames mit der längsten Ausführungszeit und wählen Sie die Tabellenzeile aus. Dadurch wird der ausgewählte Frame in der Zeitachsenansicht links herangezoomt.

    Zeitachsenansicht neben der Frames-Tabelle

  3. Suchen Sie in den Abschnitten Frame-Lebenszyklus und Threads nach relevanten Threads.

    Abschnitte „Frame-Lebenszyklus“ und „Threads“

Verzögerung unter Android 10 und niedriger erkennen

Bei Geräten mit Android 10 (API-Level 29) und niedriger werden relevante Informationen zur Grafikpipeline des Betriebssystems in einem einzelnen Abschnitt im CPU Profiler-System-Trace als Display angezeigt.

Das Fenster der Benutzeroberfläche zur Anzeige

  • Frames: In diesem Bereich werden der UI-Thread und RenderThread-Trace-Ereignisse in Ihrer App angezeigt. Ereignisse, die länger als 16 ms dauern, werden rot eingefärbt, um potenzielle Verzögerungen für Frames hervorzuheben, da sie die Frist für das Rendering mit 60 Bildern pro Sekunde (fps) überschreiten.
  • SurfaceFlinger: In diesem Abschnitt wird angezeigt, wann SurfaceFlinger die Frame-Zwischenspeicher verarbeitet. SurfaceFlinger ist ein Systemprozess, der für das Senden von Puffern an die Anzeige verantwortlich ist.
  • VSYNC: In diesem Abschnitt wird VSYNC angezeigt, ein Signal, das die Anzeigepipeline synchronisiert. Der Track zeigt das VSYNC-App-Signal an, das anzeigt, wenn Ihre App zu spät startet. Dies liegt in der Regel daran, dass der UI-Thread ausgelastet ist. Es führt während einer Animation zu einem sichtbaren Flimmern auf dem Bildschirm und erhöht die Eingabelatenz, bis die Animation oder das Scrollen abgeschlossen ist. Dies ist besonders bei Displays mit hoher Aktualisierungsrate wichtig, da diese häufiger als 60 Mal pro Sekunde oder mit einer variablen Rate auftreten können.
  • BufferQueue: In diesem Abschnitt wird angezeigt, wie viele Frame-Zwischenspeicher sich in der Warteschlange befinden und darauf warten, dass SurfaceFlinger verbraucht wird. Bei Apps, die auf Geräten mit Android 9 (API-Level 28) oder höher bereitgestellt werden, zeigt dieser Track die Pufferanzahl der Oberfläche BufferQueue (0, 1 oder 2) der App an. Mit BufferQueue können Sie den Status von Bildzwischenspeichern beim Wechsel zwischen den Android-Grafikkomponenten nachvollziehen. Ein Wert von 2 bedeutet beispielsweise, dass die Anwendung derzeit dreimal gepuffert ist, was zu einer zusätzlichen Eingabelatenz führt.

Der Abschnitt Display (Anzeige) bietet nützliche Signale zum Erkennen möglicher Verzögerungen, z. B. wenn der UI-Thread oder RenderThread länger als 16 ms dauert. Um die Ursache der Verzögerung genau zu ermitteln, können Sie den Abschnitt Threads prüfen. Dort werden die Threads angezeigt, die für das UI-Rendering relevant sind.

Der Bereich „Threads“ unter „Display“

In der Abbildung oben zeigt der Abschnitt Threads den UI-Thread (java.com.google.samples.apps.iosched), RenderThread und den Thread GPU completion. Diese Threads sind für das UI-Rendering relevant und können zur Verzögerung beitragen.

So erkennen Sie eine Verzögerung unter Android 10 oder niedriger:

  1. Sehen Sie sich unter Displaynetzwerk den Track Frames an. Die roten Rahmen sind Kandidaten für eine Untersuchung.

    Im Bereich „Frames“ unter „Display“

  2. Wenn Sie einen möglicherweise stockenden Frame gefunden haben, zoomen Sie heran, indem Sie W drücken oder mit dem Mausrad scrollen und dabei Strg (Befehl unter macOS) gedrückt halten. Zoomen Sie weiter heran, bis Sie die Trace-Ereignisse im UI-Thread und RenderThread sehen.

    Ereignisse im UI-Thread und RenderThread verfolgen

    In der Abbildung oben ist Choreographer#doFrame zu sehen, wenn der UI-Thread Choreographer aufruft, um die Animation zu koordinieren, das Layout anzusehen, Bilder zu zeichnen und ähnliche Prozesse zu erstellen. DrawFrames zeigt an, wann RenderThread tatsächliche Zeichenbefehle an die GPU sendet und ausgibt.

  3. Bei einem besonders langen Trace-Ereignis können Sie weiter heranzoomen, um herauszufinden, was für das langsame Rendering verantwortlich sein könnte. Die Abbildung oben zeigt inflate im UI-Thread, was bedeutet, dass die App Zeit darauf verwendet, das Layout zu erweitern. Wenn Sie eines der inflate-Ereignisse heranzoomen, können Sie genau feststellen, wie lange die einzelnen UI-Komponenten benötigen (siehe unten).

    Menü mit der genauen Dauer einer UI-Komponente

Weitere Informationen

Weitere Informationen zum Reduzieren der Verzögerung finden Sie unter Häufige Ursachen von Verzögerungen.