Ottimizzare la frequenza frame con la frequenza di aggiornamento adattiva

Quando viene avviata un'animazione in Android, la frequenza di aggiornamento dello schermo viene spesso aumentata al valore massimo per garantire un'esperienza fluida. Per piccole animazioni come barre di avanzamento e visualizzatori audio, questa frequenza di aggiornamento elevata non è necessaria e comporta un elevato consumo di energia.

A partire da Android 15, con la funzionalità di frequenza di aggiornamento adattiva (ARR), i dispositivi abilitati possono ridurre la residenza ad alta frequenza di aggiornamento su due fronti:

  • Grazie alle nuove ottimizzazioni per la gestione della frequenza fotogrammi della piattaforma, le app possono eseguire il rendering con una frequenza fotogrammi inferiore per impostazione predefinita e aumentare la frequenza fotogrammi solo se necessario.
  • La frequenza di aggiornamento del display si adatta dinamicamente alla frequenza di rendering dei contenuti senza ritardi.

Sebbene la maggior parte delle app debba trarre vantaggio dall'ARR senza alcuna modifica, puoi anche sostituire il comportamento predefinito della frequenza frame in base alle tue esigenze.

Questa pagina descrive quanto segue:

  • Come viene determinata la frequenza fotogrammi di ogni visualizzazione.
  • Il criterio generale per la modalità di determinazione della frequenza fotogrammi da parte dell'ARR.
  • Come ignorare manualmente il comportamento predefinito della frequenza fotogrammi.

Il meccanismo di voto di View

Nel sistema di visualizzazione di Android, ogni visualizzazione nella gerarchia dell'interfaccia utente può esprimere la frequenza frame preferita. Queste preferenze vengono raccolte e combinate per determinare una frequenza frame finale per ogni fotogramma. Questo viene ottenuto tramite un meccanismo di voto in cui ogni visualizzazione vota in base al proprio attributo frequenza frame, che può essere una categoria o una frequenza specifica. In genere, le visualizzazioni vengono votate quando vengono disegnate o aggiornate. Questi voti vengono combinati per determinare una frequenza frame finale, che viene poi inviata al livello inferiore come suggerimento per il rendering.

Al momento, la maggior parte delle visualizzazioni ha per impostazione predefinita una frequenza frame "Normale", spesso impostata su 60 Hz. Per frequenze frame più elevate, puoi utilizzare API specifiche per personalizzare le preferenze, con il sistema che in genere seleziona la frequenza frame più elevata. Per ulteriori informazioni sull'utilizzo di queste API, consulta la sezione Impostare la frequenza o la categoria del frame. Le norme generali relative alle frequenze di frame sono descritte nella sezione Norme generali relative alla frequenza di annunci riprodotti.

Categorie di frequenza fotogrammi

Nella classe View sono disponibili diverse categorie di frequenza fotogrammi che possono essere utilizzate per il voto. La descrizione di ogni categoria è la seguente:

  • REQUESTED_FRAME_RATE_CATEGORY_DEFAULT: questo valore può essere impostato per ripristinare il comportamento predefinito, indicando che questa visualizzazione non contiene dati sulla frequenza fotogrammi.
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE: la visualizzazione non influisce esplicitamente sulla frequenza frame. Ciò significa che, anche se la visualizzazione è attiva, il framework non la prenderà in considerazione per determinare la frequenza frame.
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL: indica una frequenza fotogrammi media adatta per le animazioni che non richiedono frequenze fotogrammi più elevate o che non traggono vantaggio da un'elevata fluidità. In genere è di 60 Hz o poco più.
  • REQUESTED_FRAME_RATE_CATEGORY_HIGH: indica una frequenza fotogrammi adatta per le animazioni che richiedono una frequenza fotogrammi elevata, il che può aumentare la fluidità, ma anche l'utilizzo di energia.

Una vista viene votata solo se richiede il ricalcolo. La frequenza fotogrammi finale viene determinata dalla votazione più alta. Ad esempio, se tutti i voti sono per "Normale", viene selezionato "Normale". Quando vengono registrati voti sia per "Normale" che per "Alto", viene scelto "Alto".

Frequenza fotogrammi

Oltre alle categorie di frequenza fotogrammi, una visualizzazione può anche specificare una frequenza fotogrammi preferita, ad esempio 30, 60 o 120 Hz. Quando vengono espressi più voti per la frequenza fotogrammi, la frequenza fotogrammi finale viene determinata dalle seguenti regole:

  • Moltiplicatori tra loro: se le frequenze frame votate sono moltiplicatori tra loro, viene scelto il valore più alto. Ad esempio, se sono presenti due voti, 30 Hz e 90 Hz, viene selezionata la frequenza frame finale di 90 Hz.
  • Non sono multipli l'uno dell'altro:
    • Se uno dei voti è superiore a 60 Hz, viene conteggiato come voto "Alto".
    • Se tutti i voti sono pari o inferiori a 60 Hz, viene conteggiato come voto "Normale".

Inoltre, se è presente una combinazione di valori e categorie di frequenza frame, in genere il valore più alto determina la frequenza di rendering finale. Ad esempio, con una combinazione di un voto a 60 Hz e un voto "Alto" o un voto a 120 Hz e un voto "Normale", la frequenza di rendering viene in genere impostata su 120 Hz.

Oltre ai voti di un'app, potrebbero essere inviati anche altri suggerimenti al livello di livello inferiore da componenti diversi all'interno dello stesso frame. Molti di questi possono provenire da componenti dell'interfaccia utente di sistema, come l'area notifiche, la barra di stato, la barra di navigazione e altri. I valori finali della frequenza frame vengono stabiliti in base ai voti di più componenti.

Imposta la frequenza fotogrammi o la categoria

In determinate circostanze, potresti avere una frequenza fotogrammi preferita per una visualizzazione. Ad esempio, puoi impostare la frequenza fotogrammi preferita su "Alta" per una visualizzazione per aumentare la frequenza fotogrammi se un'animazione non è fluida. Inoltre, se un video contiene un'animazione lenta o statica (in genere riprodotta a 24 o 30 Hz), potresti preferire che l'animazione venga riprodotta a una frequenza inferiore a "Normale" per ridurre il consumo di energia.

Puoi utilizzare le API setRequestedFrameRate() e getRequestedFrameRate() per designare la frequenza fotogrammi o la categoria preferita di una determinata visualizzazione.

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);

Per un esempio di utilizzo, consulta TextureView.

Norme generali relative all'ARR

Nella sezione precedente abbiamo spiegato che la maggior parte delle animazioni viene visualizzata a 60 Hz per impostazione predefinita, poiché per ogni visualizzazione è impostata la frequenza frame "Normale". Tuttavia, esistono delle eccezioni in cui la frequenza fotogrammi viene aumentata a "Alta" per garantire animazioni più fluide.

Le norme generali relative all'ARR sono le seguenti:

  • Boost tocco: quando viene rilevato un evento tocco (MotionEvent.ACTION_DOWN), la frequenza di aggiornamento viene aumentata a "Alta" per un po' di tempo dopo il rilascio del tocco per mantenere la reattività.
  • Gesti scorrimento: i gesti scorrimento vengono gestiti in modo diverso: la frequenza di aggiornamento diminuisce gradualmente man mano che la velocità di scorrimento diminuisce. Puoi trovare dettagli su questo comportamento nella sezione Miglioramento dello scorrimento.
  • Avvio delle app e transizioni tra le finestre: la frequenza di aggiornamento viene aumentata anche per un breve periodo di tempo durante l'avvio delle app, l'inizializzazione delle finestre e le transizioni tra le finestre per garantire un'esperienza visiva fluida.
  • Animazioni: le animazioni che prevedono movimenti o modifiche delle dimensioni ricevono automaticamente una frequenza di aggiornamento più elevata per migliorare la fluidità quando la posizione o le dimensioni di una vista cambiano.
  • SurfaceView e TextureView: le frequenze fotogrammi impostate esplicitamente per TextureView e SurfaceView vengono rispettate e applicate di conseguenza.

Attivare e disattivare l'aumento della sensibilità al tocco

Puoi attivare e/o disattivare il potenziamento tocco a livello di Window. Per impostazione predefinita, quando un utente tocca e solleva il dito dallo schermo, la frequenza di aggiornamento aumenta per un po' di tempo. Le API setFrameRateBoostOnTouchEnabled() e getFrameRateBoostOnTouchEnabled() ti consentono di impedire l'aumento della frequenza di aggiornamento quando viene toccato un Window specifico.

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()

Miglioramento dello scorrimento

Un caso d'uso chiave per l'ottimizzazione dinamica della frequenza frame è migliorare l'esperienza di scorrimento (spostamento rapido). Molte applicazioni si basano molto sullo scorrimento verso l'alto da parte degli utenti per visualizzare nuovi contenuti. Il miglioramento dello scorrimento ARR regola dinamicamente la frequenza di aggiornamento man mano che il gesto di scorrimento rallenta, riducendo gradualmente la frequenza frame. Ciò consente un rendering più efficiente mantenendo scorrevole la visualizzazione.

Questo miglioramento si applica specificamente ai componenti dell'interfaccia utente scorrevoli, tra cui ScrollView, ListView e GridView, e potrebbe non essere disponibile per tutte le implementazioni personalizzate.

La funzionalità di scorrimento dell'ARR è disponibile per RecyclerView e NestedScrollView. Per attivare questa funzionalità nella tua app, esegui l'upgrade alle ultime versioni di AndroidX.recyclerview e AndroidX.core. Per maggiori dettagli, consulta la tabella seguente.

Raccolta

Versione

AndroidX.recyclerview

1.4.0

AndroidX.core

1.15.0

Impostare le informazioni sulla velocità

Se hai un componente scorrevole personalizzato e vuoi sfruttare la funzionalità di scorrimento, chiama setFrameContentVelocity() su ogni frame durante lo scorrimento fluido o la scorrimento rapido. Per un esempio, consulta il seguente snippet di codice:

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()

Per altri esempi, consulta RecyclerView e ScrollView. Per impostare correttamente la velocità, calcola manualmente la velocità dei contenuti (pixel al secondo) se le informazioni richieste non possono essere ottenute da Scroller o OverScroller.

Tieni presente che se setFrameContentVelocity() e getFrameContentVelocity() vengono chiamati su visualizzazioni che non sono componenti scorrevoli, non avranno alcun effetto, poiché il movimento attiva automaticamente un aumento della frequenza dei fotogrammi in base al criterio corrente.

Le informazioni sulla velocità sono fondamentali per regolare la frequenza di aggiornamento. Ad esempio, consideriamo il gesto di lancio. All'inizio, la velocità di un movimento può essere elevata, il che richiede una frequenza di rendering più elevata per garantire la fluidità. Man mano che il gesto procede, la velocità diminuisce, consentendo di ridurre la frequenza di aggiornamento.

Attivare e disattivare l'ARR

L'ARR è attivato per impostazione predefinita per migliorare l'efficienza energetica. Anche se puoi disattivare questa funzionalità, non è consigliabile, in quanto l'app consumerebbe più energia. Valuta la possibilità di disattivare questa funzionalità solo se riscontri problemi che influiscono in modo significativo sull'esperienza utente.

Per attivare o disattivare l'ARR, utilizza l'API setFrameRatePowerSavingsBalanced() su un Window o l'API isFrameRatePowerSavingsBalanced() tramite il file styles.xml.

Lo snippet seguente mostra come attivare o disattivare l'ARR su un Window:

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()

Per disattivare l'ARR tramite il file styles.xml, aggiungi il seguente elemento al tuo stile in res/values/styles.xml:

<style name="frameRatePowerSavingsBalancedDisabled">
    <item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
</style>