Quando viene avviata un'animazione in Android, spesso il display aumenta la frequenza di aggiornamento massima per garantire un'esperienza fluida. Per le piccole animazioni come le barre di avanzamento e i visualizzatori audio, questa frequenza di aggiornamento elevata non è necessaria e comporta un elevato consumo energetico.
A partire da Android 15, con la funzionalità di frequenza di aggiornamento adattiva (ARR), i dispositivi abilitati possono ridurre la permanenza di una frequenza di aggiornamento elevata su due fronti:
- Grazie alle nuove ottimizzazioni della gestione della frequenza fotogrammi della piattaforma, le app possono eseguire il rendering a una frequenza fotogrammi inferiore per impostazione predefinita e aumentare la frequenza fotogrammi solo quando necessario.
- La frequenza di aggiornamento del display corrisponde dinamicamente alla frequenza di rendering dei contenuti senza problemi.
Sebbene la maggior parte delle app dovrebbe trarre vantaggio dall'ARR senza alcuna modifica, puoi anche ignorare il comportamento predefinito della frequenza dei fotogrammi in base alle tue esigenze.
Questa pagina descrive quanto segue:
- Come viene determinata la frequenza dei fotogrammi di ogni visualizzazione.
- I criteri generali per la determinazione della frequenza fotogrammi da parte di ARR.
- Come puoi ignorare manualmente il comportamento predefinito della frequenza fotogrammi.
Il meccanismo di voto di Visualizza
Nel sistema di visualizzazione di Android, ogni visualizzazione nella gerarchia dell'interfaccia utente può esprimere la propria frequenza dei fotogrammi preferita. Queste preferenze vengono raccolte e combinate per determinare un frame rate finale per ogni frame. Ciò si ottiene tramite un meccanismo di voto in cui ogni visualizzazione vota in base al proprio attributo di frame rate, che può essere una categoria o una frequenza specifica. Le visualizzazioni vengono in genere votate quando vengono disegnate o aggiornate. Questi voti vengono combinati per determinare un frame rate finale, che viene poi inviato al livello inferiore come suggerimento per il rendering.
Attualmente, la maggior parte delle visualizzazioni è impostata su una frequenza dei fotogrammi "Normale", spesso impostata su 60 Hz. Per frequenze dei fotogrammi più elevate, puoi utilizzare API specifiche per personalizzare le preferenze, con il sistema che in genere seleziona la frequenza dei fotogrammi più alta. Per ulteriori informazioni sull'utilizzo di queste API, consulta la sezione Impostare il frame rate o la categoria. I criteri generali relativi ai frame rate sono descritti nella sezione Norme generali ARR.
Categorie di frame rate
Nella classe View
, sono presenti diverse categorie di frame rate che possono essere
utilizzate nella votazione. Di seguito è riportata la descrizione di ogni categoria:
REQUESTED_FRAME_RATE_CATEGORY_DEFAULT
: questo valore può essere impostato per tornare al comportamento predefinito, indicando che questa vista non ha dati per la frequenza fotogrammi.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE
: la visualizzazione non influirà esplicitamente sul frame rate. Ciò significa che, anche se la visualizzazione è attiva, il framework non la prenderà in considerazione per determinare il frame rateREQUESTED_FRAME_RATE_CATEGORY_NORMAL
: indica una frequenza fotogrammi media adatta alle animazioni che non richiedono frequenze fotogrammi più elevate o che non traggono vantaggio da un'elevata fluidità. Di solito è 60 Hz o un valore simile.REQUESTED_FRAME_RATE_CATEGORY_HIGH
: indica una frequenza fotogrammi adatta alle animazioni che richiedono una frequenza fotogrammi elevata, il che può aumentare la fluidità, ma anche il consumo energetico.
A Visualizza voti solo se richiede il ridisegno. Il frame rate finale è determinato dal voto più alto. Ad esempio, se tutti i voti sono per "Normale", viene selezionato "Normale". Quando si verificano voti "Normale" e "Alto", viene scelto "Alto".
Frequenza fotogrammi
Oltre alle categorie di frame rate, una visualizzazione può anche specificare un frame rate preferito, ad esempio 30, 60 o 120 Hz. Quando vengono espressi più voti per il frame rate, il frame rate finale viene determinato dalle seguenti regole:
- Multipli l'uno dell'altro: se i frame rate votati sono multipli l'uno dell'altro, viene scelto il valore più alto. Ad esempio, se ci sono due voti, 30 Hz e 90 Hz, viene selezionato 90 Hz come frame rate finale.
- Non sono multipli l'uno dell'altro:
- Se uno dei voti è superiore a 60 Hz, viene considerato "Alto".
- Se tutti i voti sono pari o inferiori a 60 Hz, vengono conteggiati come "Normali".
Inoltre, se è presente una combinazione di valori di frame rate e categorie di frame rate, il valore più alto determina in genere 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 altri suggerimenti al livello inferiore da diversi componenti all'interno dello stesso frame. Molti di questi possono provenire da componenti dell'interfaccia utente di sistema, come la tendina delle notifiche, la barra di stato, la barra di navigazione e altri. I valori finali del frame rate sono determinati 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 appare fluida. Inoltre, se è presente un'animazione lenta o statica su un video (in genere riprodotto a 24 o 30 Hz), potresti preferire che l'animazione venga riprodotta a una velocità inferiore a "Normale" per ridurre il consumo energetico.
Puoi utilizzare le API setRequestedFrameRate()
e
getRequestedFrameRate()
per designare la categoria o il frame rate preferito 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, vedi TextureView
.
Norme generali ARR
Nella sezione precedente abbiamo spiegato che la maggior parte delle animazioni viene visualizzata a 60 Hz per impostazione predefinita, poiché ogni visualizzazione ha "Normale" come frame rate preferito. Tuttavia, ci sono eccezioni in cui la frequenza fotogrammi viene aumentata a "Alta" per garantire animazioni più fluide.
Le norme generali relative all'ARR sono le seguenti:
- Potenziamento del tocco: quando viene rilevato un evento di 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 di scorrimento: i gesti di scorrimento vengono gestiti in modo diverso: la frequenza di aggiornamento diminuisce gradualmente man mano che la velocità di scorrimento rallenta. Puoi trovare i dettagli su questo comportamento nella sezione Miglioramento dello scorrimento.
- Avvio di app e transizioni tra finestre: la frequenza di aggiornamento viene aumentata anche per un po' di tempo durante gli avvii di app, l'inizializzazione delle finestre e le transizioni tra finestre per garantire un'esperienza visiva fluida.
- Animazioni: le animazioni che comportano 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 visualizzazione cambiano.
SurfaceView
eTextureView
: le frequenze fotogrammi impostate in modo esplicito perTextureView
eSurfaceView
vengono rispettate e applicate di conseguenza.
Attivare e disattivare il potenziamento del tocco
Puoi attivare e/o disattivare il potenziamento del tocco a livello di Window
. Per impostazione predefinita,
quando un utente tocca e solleva il dito dallo schermo, la frequenza di rendering
aumenta per un po' di tempo. Le API setFrameRateBoostOnTouchEnabled()
e
getFrameRateBoostOnTouchEnabled()
ti consentono di impedire l'aumento
della frequenza di rendering 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 del frame rate è il miglioramento dell'esperienza di scorrimento (fling). Molte applicazioni si basano molto sullo scorrimento verso l'alto degli utenti per visualizzare nuovi contenuti. Il miglioramento dello scorrimento ARR regola dinamicamente la frequenza di aggiornamento quando il gesto di scorrimento rallenta, riducendo gradualmente il frame rate. Ciò consente un rendering più efficiente mantenendo uno scorrimento fluido.
Questo miglioramento si applica in modo specifico ai componenti UI 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 versioni più recenti di AndroidX.recyclerview
e AndroidX.core
. Per maggiori dettagli, consulta la tabella seguente.
Raccolta |
Versione |
|
1.4.0 |
|
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 lo scorrimento rapido. Per un esempio, vedi 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 una frequenza dei fotogrammi maggiore in base alle norme attuali.
Le informazioni sulla velocità sono fondamentali per regolare la frequenza di rendering. Ad esempio, considera il gesto di scorrimento rapido. All'inizio, la velocità di un lancio può essere elevata, il che richiede una frequenza di rendering più alta per garantire la fluidità. Man mano che il gesto procede, la velocità diminuisce, consentendo di abbassare la frequenza di rendering.
Attivare e disattivare ARR
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. Prendi in considerazione la disattivazione di questa funzionalità solo se riscontri problemi che influenzano in modo significativo l'esperienza utente.
Per attivare o disattivare ARR, utilizza l'API
setFrameRatePowerSavingsBalanced()
su un Window
oppure l'API
isFrameRatePowerSavingsBalanced()
tramite il file styles.xml
.
Il seguente snippet mostra come attivare o disattivare 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 ARR tramite il file styles.xml
, aggiungi il seguente elemento allo stile in res/values/styles.xml
:
<style name="frameRatePowerSavingsBalancedDisabled">
<item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
</style>
ARR per Compose
Compose 1.9 aggiunge anche il supporto della frequenza di aggiornamento adattiva.
Nel sistema di visualizzazione, utilizzi il metodo setRequestedFrameRate()
per
richiedere una frequenza dei fotogrammi specifica per una visualizzazione. In Compose, un nuovo modificatore consente di
specificare la frequenza frame per un elemento componibile. Questo modificatore funziona
in modo simile a setRequestedFrameRate()
, accettando un valore
di frequenza fotogrammi positivo (in Hz) o una categoria di frequenza fotogrammi predefinita,
FrameRateCategory
.
Le firme delle API sono le seguenti:
Modifier.preferredFrameRate(frameRate: Float)
Modifier.preferredFrameRate(frameRateCategory: FrameRateCategory)
Nello snippet riportato di seguito, il nuovo modificatore della frequenza frame (Modifier.requestedFrameRate(120f))
viene applicato a un elemento componibile Text
. Questo modificatore fa sì che il composable Text
richieda una frequenza dei fotogrammi preferita di 120 quando viene disegnato o animato (ad esempio, con modifiche all'opacità):
var targetAlpha by remember { mutableFloatStateOf(1f) }
val alpha by
animateFloatAsState(
targetValue = targetAlpha,
animationSpec = tween(durationMillis = 1000)
)
Button(
onClick = { targetAlpha = if (targetAlpha == 1f) 0.2f else 1f },
modifier =
Modifier.background(LocalContentColor.current.copy(alpha = alpha))
) {
Text(
text = "Click",
color = LocalContentColor.current.copy(alpha = alpha),
modifier = Modifier.preferredFrameRate(120f)
// You can also pass frame rate category such as FrameRateCategory.High to increase the frame rate
)
}
Le frequenze dei fotogrammi preferite di tutti i componenti vengono quindi raccolte e
consolidate per determinare la frequenza dei fotogrammi finale per ogni fotogramma. Per maggiori dettagli,
consulta SetFrameRateSample
e
SetFrameRateCategorySample
.