Wenn in Android eine Animation gestartet wird, wird die Displayaktualisierungsrate häufig auf die maximale Bildwiederholrate erhöht, um eine flüssige Darstellung zu ermöglichen. Für kleine Animationen wie Fortschrittsbalken und Audiovisualisierungen ist diese hohe Bildwiederholrate nicht erforderlich und führt zu einem hohen Stromverbrauch.
Ab Android 15 können Geräte mit der Funktion für die adaptive Bildwiederholrate (ARR) die Verweildauer bei hoher Bildwiederholrate auf zwei Arten reduzieren:
- Durch die neuen Optimierungen der Framerate-Verwaltung auf der Plattform können Apps standardmäßig mit einer niedrigeren Framerate gerendert und nur bei Bedarf auf eine hohe Framerate hochgeschraubt werden.
- Die Displayaktualisierungsrate wird dynamisch an die Inhaltsrendering-Rate angepasst, ohne Ruckler.
Die meisten Apps sollten ohne Änderungen von der automatischen Framerate profitieren. Sie können das Standardverhalten der Framerate aber auch bei Bedarf überschreiben.
Auf dieser Seite wird Folgendes beschrieben:
- So wird die Framerate der einzelnen Ansichten ermittelt.
- Die allgemeine Richtlinie, nach der ARR die Framerate festlegt.
- So kannst du das Standardverhalten der Framerate manuell überschreiben.
Der Abstimmungsmechanismus für YouTube-Videos
Im View-System von Android kann jede Ansicht in der UI-Hierarchie ihre bevorzugte Framerate angeben. Diese Einstellungen werden erfasst und kombiniert, um eine endgültige Framerate für jeden Frame zu bestimmen. Dazu wird ein Abstimmungsmechanismus verwendet, bei dem jede Wiedergabe basierend auf ihrem Framerate-Attribut abstimmt. Das kann eine Kategorie oder eine bestimmte Rate sein. Bei Ansichten wird in der Regel abgestimmt, wenn sie erstellt oder aktualisiert werden. Diese Stimmen werden kombiniert, um eine endgültige Framerate zu bestimmen, die dann als Hinweis für das Rendering an die untergeordnete Ebene gesendet wird.
Derzeit ist für die meisten Ansichten standardmäßig eine „normale“ Framerate festgelegt, die oft auf 60 Hz gesetzt ist. Für höhere Frameraten kannst du bestimmte APIs verwenden, um die Einstellungen anzupassen. Das System wählt in der Regel die höchste Framerate aus. Weitere Informationen zur Verwendung dieser APIs findest du im Abschnitt Framerate oder Kategorie festlegen. Die allgemeinen Richtlinien zu Frameraten werden im Abschnitt Allgemeine Richtlinien für die automatische Wiedergaberate beschrieben.
Framerate-Kategorien
In der Klasse View
gibt es verschiedene Framerate-Kategorien, die bei der Abstimmung verwendet werden können. Die einzelnen Kategorien werden wie folgt beschrieben:
REQUESTED_FRAME_RATE_CATEGORY_DEFAULT
: Mit diesem Wert können Sie zum Standardverhalten zurückkehren. Das bedeutet, dass für diese Ansicht keine Daten für die Framerate vorhanden sind.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE
: Die Ansicht hat keinen Einfluss auf die Framerate. Das bedeutet, dass das Framework die Ansicht auch dann nicht bei der Bestimmung der Framerate berücksichtigt, wenn sie aktiv ist.REQUESTED_FRAME_RATE_CATEGORY_NORMAL
: Gibt eine mittlere Framerate an, die für Animationen geeignet ist, die keine höheren Frameraten erfordern oder nicht von einer hohen Flüssigkeit profitieren. Normalerweise ist das 60 Hz oder in der Nähe davon.REQUESTED_FRAME_RATE_CATEGORY_HIGH
: Gibt eine Framerate an, die für Animationen geeignet ist, die eine hohe Framerate erfordern. Dies kann die Laufruhe verbessern, aber auch den Stromverbrauch erhöhen.
Eine Ansicht wird nur dann neu gerendert, wenn eine Abstimmung dafür erfolgt. Die endgültige Framerate wird durch die höchste Abstimmung bestimmt. Wenn beispielsweise alle Stimmen für „Normal“ abgegeben wurden, wird „Normal“ ausgewählt. Wenn sowohl „Normal“ als auch „Hoch“ ausgewählt wurde, wird „Hoch“ ausgewählt.
Framerate
Neben den Framerate-Kategorien kann für eine Wiedergabe auch eine bevorzugte Framerate angegeben werden, z. B. 30, 60 oder 120 Hz. Wenn mehrere Stimmen für eine Framerate abgegeben werden, wird die endgültige Framerate anhand der folgenden Regeln ermittelt:
- Ein Vielfaches voneinander: Wenn die ausgewählten Frameraten ein Vielfaches voneinander sind, wird der höchste Wert ausgewählt. Wenn beispielsweise zwei Stimmen abgegeben wurden – 30 Hz und 90 Hz –, wird 90 Hz als endgültige Framerate ausgewählt.
- Keine Vielfache voneinander:
- Wenn eine der Bewertungen über 60 Hz liegt, wird sie als „Hoch“ gewertet.
- Wenn alle Stimmen 60 Hz oder weniger betragen, wird dies als „Normal“ gewertet.
Wenn sowohl Framerate-Werte als auch Framerate-Kategorien kombiniert werden, wird die endgültige Renderingrate in der Regel durch den höheren Wert bestimmt. Bei einer Kombination aus einer Abstimmung für 60 Hz und „Hoch“ oder einer Abstimmung für 120 Hz und „Normal“ wird die Renderrate in der Regel auf 120 Hz festgelegt.
Zusätzlich zu den Stimmen aus einer App können auch andere Hinweise von verschiedenen Komponenten innerhalb desselben Frames an die untergeordnete Schicht gesendet werden. Viele davon können von System-UI-Komponenten stammen, z. B. vom Benachrichtigungs-Schieberegler, der Statusleiste oder der Navigationsleiste. Die endgültigen Werte für die Framerate werden anhand der Stimmen mehrerer Komponenten ermittelt.
Framerate oder Kategorie festlegen
Unter bestimmten Umständen haben Sie möglicherweise eine bevorzugte Framerate für eine Ansicht. Sie können beispielsweise die bevorzugte Framerate für eine Ansicht auf „Hoch“ festlegen, um die Framerate zu erhöhen, wenn eine Animation nicht flüssig erscheint. Wenn sich über einem Video eine langsame oder statische Animation abspielt (normalerweise mit 24 oder 30 Hz), kann es sinnvoll sein, die Animation mit einer niedrigeren Rate als „Normal“ auszuführen, um den Energieverbrauch zu senken.
Mit den APIs setRequestedFrameRate()
und getRequestedFrameRate()
kannst du die bevorzugte Framerate oder Kategorie einer bestimmten Wiedergabe festlegen.
Kotlin
// Set the preferred frame rate category to a View // set the frame rate category to NORMAL view.requestedFrameRate = View.REQUESTED_FRAME_RATE_CATEGORY_NORMAL // set the frame rate category to HIGH view.requestedFrameRate = View.REQUESTED_FRAME_RATE_CATEGORY_HIGH // reset the frame rate category view.requestedFrameRate = View.REQUESTED_FRAME_RATE_CATEGORY_DEFAULT // Set the preferred frame rate to a View // set the frame rate to 30 view.requestedFrameRate = 30f // set the frame rate to 60 view.requestedFrameRate = 60f // set the frame rate to 120 view.requestedFrameRate = 120f
Java
// Set the preferred frame rate category to a View // set the frame rate category to NORMAL view.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_NORMAL); // set the frame rate category to HIGH view.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_HIGH); // reset the frame rate category view.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_DEFAULT); // Set the preferred frame rate to a View // set the frame rate to 30 view.setRequestedFrameRate(30); // set the frame rate to 60 view.setRequestedFrameRate(60); // set the frame rate to 120 view.setRequestedFrameRate(120);
Ein Anwendungsbeispiel finden Sie unter TextureView
.
Allgemeine Richtlinie zu den Anforderungen an die Zugriffsrechte
Im vorherigen Abschnitt haben wir festgestellt, dass die meisten Animationen standardmäßig mit 60 Hz angezeigt werden, da für jede Ansicht „Normal“ als bevorzugte Framerate festgelegt ist. Es gibt jedoch Ausnahmen, bei denen die Framerate auf „Hoch“ erhöht wird, um flüssigere Animationen zu ermöglichen.
Die allgemeine ARR-Richtlinie lautet:
- Touch-Optimierung: Wenn ein Touch-Ereignis (
MotionEvent.ACTION_DOWN
) erkannt wird, wird die Bildwiederholrate nach dem Loslassen der Berührung für einige Zeit auf „Hoch“ erhöht, um die Reaktionsfähigkeit aufrechtzuerhalten. - Wisch-Gesten: Wisch-Gesten werden anders behandelt. Die Aktualisierungsrate nimmt allmählich ab, wenn die Wischgeschwindigkeit sinkt. Weitere Informationen zu diesem Verhalten finden Sie im Abschnitt Verbesserungen beim Scrollen.
- App-Start und Fensterübergänge: Die Bildwiederholrate wird auch für einige Zeit beim Starten von Apps, bei der Fensterinitialisierung und bei Fensterübergängen erhöht, um eine flüssige Bildwiedergabe zu ermöglichen.
- Animationen: Animationen mit Bewegungen oder Größenänderungen erhalten automatisch eine höhere Bildwiederholrate, um die Bildflüssigkeit zu verbessern, wenn sich die Position oder Größe einer Ansicht ändert.
SurfaceView
undTextureView
: Frameraten, die explizit fürTextureView
undSurfaceView
festgelegt wurden, werden berücksichtigt und entsprechend angewendet.
Touch-Optimierung aktivieren und deaktivieren
Sie können die Touch-Beschleunigung auf Window
-Ebene aktivieren und/oder deaktivieren. Wenn ein Nutzer den Bildschirm berührt und den Finger wieder vom Display nimmt, erhöht sich standardmäßig die Bildwiederholrate für einige Zeit. Mit den APIs setFrameRateBoostOnTouchEnabled()
und getFrameRateBoostOnTouchEnabled()
können Sie verhindern, dass die Bildwiederholrate erhöht wird, wenn eine bestimmte Window
berührt wird.
Kotlin
// disable touch boost on a Window window.isFrameRateBoostOnTouchEnabled = false // enable touch boost on a Window window.isFrameRateBoostOnTouchEnabled = true // check if touch boost is enabled on a Window val isTouchBoostEnabled = window.isFrameRateBoostOnTouchEnabled
Java
// disable touch boost on a Window window.setFrameRateBoostOnTouchEnabled(false) // enable touch boost on a Window window.setFrameRateBoostOnTouchEnabled(true) // check if touch boost is enabled on a Window window.getFrameRateBoostOnTouchEnabled()
Verbesserungen beim Scrollen
Ein wichtiger Anwendungsfall für die dynamische Optimierung der Framerate ist die Verbesserung des Scrollens (Wischens). Viele Apps setzen stark darauf, dass Nutzer nach oben wischen, um sich neue Inhalte anzusehen. Die ARR-Scroll-Optimierung passt die Bildwiederholrate dynamisch an, wenn die Wischbewegung langsamer wird, und reduziert so nach und nach die Framerate. Das ermöglicht ein effizienteres Rendering bei gleichzeitig flüssigem Scrollen.
Diese Verbesserung gilt speziell für scrollbare UI-Komponenten, einschließlich ScrollView
, ListView
und GridView
. Sie ist möglicherweise nicht für alle benutzerdefinierten Implementierungen verfügbar.
Die ARR-Scrollfunktion ist für RecyclerView
und NestedScrollView
verfügbar. Wenn Sie diese Funktion in Ihrer App aktivieren möchten, führen Sie ein Upgrade auf die neuesten Versionen von AndroidX.recyclerview
und AndroidX.core
durch. Weitere Informationen finden Sie in der folgenden Tabelle.
Mediathek |
Version |
|
1.4.0 |
|
1.15.0 |
Geschwindigkeitsinformationen festlegen
Wenn Sie eine benutzerdefinierte scrollbare Komponente haben und die Scrollfunktion nutzen möchten, rufen Sie setFrameContentVelocity()
für jeden Frame auf, während Sie die Funktion „Gleitendes Scrollen“ oder „Wischen“ verwenden. Hier ein Beispiel für ein Code-Snippet:
Kotlin
// set the velocity to a View (1000 pixels/Second) view.frameContentVelocity = 1000f // get the velocity of a View val velocity = view.frameContentVelocity
Java
// set the velocity to a View view.setFrameContentVelocity(velocity); // get the velocity of a View final float velocity = view.getFrameContentVelocity()
Weitere Beispiele finden Sie unter RecyclerView
und ScrollView
. Wenn die erforderlichen Informationen nicht über Scroller
oder OverScroller
abgerufen werden können, berechne die Inhaltsgeschwindigkeit (Pixel pro Sekunde) manuell, um die Geschwindigkeit korrekt festzulegen.
Wenn setFrameContentVelocity()
und getFrameContentVelocity()
auf Ansichten aufgerufen werden, die keine scrollbaren Komponenten sind, haben sie keine Auswirkungen, da Bewegungen automatisch eine erhöhte Framerate auslösen, die auf der aktuellen Richtlinie basiert.
Die Informationen zur Geschwindigkeit sind entscheidend für die Anpassung der Bildwiederholrate. Betrachten Sie beispielsweise die Wischgeste. Zu Beginn kann die Geschwindigkeit eines Wischs hoch sein, was eine höhere Renderrate erfordert, um für eine flüssige Wiedergabe zu sorgen. Im Verlauf der Geste nimmt die Geschwindigkeit ab, sodass die Renderrate gesenkt werden kann.
ARR aktivieren und deaktivieren
Die automatische Helligkeitsanpassung ist standardmäßig aktiviert, um die Energieeffizienz zu verbessern. Sie können diese Funktion zwar deaktivieren, dies wird jedoch nicht empfohlen, da die App dann mehr Strom verbraucht. Deaktivieren Sie diese Funktion nur, wenn Probleme auftreten, die die Nutzerfreundlichkeit erheblich beeinträchtigen.
Wenn Sie die automatische Preisanpassung aktivieren oder deaktivieren möchten, verwenden Sie die setFrameRatePowerSavingsBalanced()
API in einer Window
oder die isFrameRatePowerSavingsBalanced()
API über Ihre styles.xml
-Datei.
Im folgenden Snippet wird gezeigt, wie du die automatische Antwort auf einer Window
aktivierst oder deaktivierst:
Kotlin
// disable ARR on a Window window.isFrameRatePowerSavingsBalanced = false // enable ARR on a Window window.isFrameRatePowerSavingsBalanced = true // check if ARR is enabled on a Window val isAdaptiveRefreshRateEnabled = window.isFrameRatePowerSavingsBalanced
Java
// disable ARR on a Window window.setFrameRatePowerSavingsBalanced(false) // enable ARR on a Window window.setFrameRatePowerSavingsBalanced(true) // check if ARR is enabled on a Window window.isFrameRatePowerSavingsBalanced()
Wenn Sie die automatische Antwort über die Datei styles.xml
deaktivieren möchten, fügen Sie Ihrem Stil in res/values/styles.xml
den folgenden Artikel hinzu:
<style name="frameRatePowerSavingsBalancedDisabled">
<item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
</style>