Cuando se inicia una animación en Android, la pantalla suele aumentar a la frecuencia de actualización máxima para garantizar una experiencia fluida. Para animaciones pequeñas, como barras de progreso y visualizadores de audio, esta alta frecuencia de actualización no es necesaria y genera un alto consumo de energía.
A partir de Android 15, con la función de frecuencia de actualización adaptativa (ARR), los dispositivos habilitados pueden reducir la residencia de alta frecuencia de actualización en dos frentes:
- Con las nuevas optimizaciones de administración de la velocidad de fotogramas de la plataforma, las apps pueden renderizarse con una velocidad de fotogramas más baja de forma predeterminada y solo aumentar a una velocidad de fotogramas alta cuando sea necesario.
- La frecuencia de actualización de la pantalla coincide de forma dinámica con la velocidad de renderización del contenido sin generar retrasos.
Si bien la mayoría de las apps deberían beneficiarse del ARR sin ninguna modificación, también puedes anular el comportamiento predeterminado de la velocidad de fotogramas según sea necesario.
En esta página, se describe lo siguiente:
- Cómo se determina la velocidad de fotogramas de cada vista
- Es la política general sobre cómo la ARR determina en qué se establece la velocidad de fotogramas.
- Cómo puedes anular de forma manual el comportamiento predeterminado de la velocidad de fotogramas
El mecanismo de votación de View
En el sistema de View de Android, cada View en la jerarquía de la IU puede expresar su frecuencia de fotogramas preferida. Estas preferencias se recopilan y combinan para determinar una velocidad de fotogramas final para cada fotograma. Esto se logra a través de un mecanismo de votación en el que cada vista vota en función de su atributo de velocidad de fotogramas, que puede ser una categoría o una velocidad específica. Por lo general, las vistas votan cuando se dibujan o actualizan. Estos votos se combinan para determinar una velocidad de fotogramas final, que luego se envía a la capa de nivel inferior como una sugerencia para la renderización.
Actualmente, la mayoría de las vistas tienen una velocidad de fotogramas "Normal" predeterminada, que suele establecerse en 60 Hz. Para velocidades de fotogramas más altas, puedes usar APIs específicas para personalizar las preferencias, y el sistema suele seleccionar la velocidad de fotogramas más alta. Para obtener más información sobre el uso de estas APIs, consulta la sección Cómo configurar la frecuencia de fotogramas o la categoría. Las políticas generales sobre las tasas de fotogramas se describen en la sección Política general de ARR.
Categorías de velocidad de fotogramas
En la clase View
, hay diferentes categorías de velocidad de fotogramas que se pueden usar en la votación. La descripción de cada categoría es la siguiente:
REQUESTED_FRAME_RATE_CATEGORY_DEFAULT
: Este valor se puede configurar para que vuelva al comportamiento predeterminado, lo que indica que esta vista no tiene datos para la velocidad de fotogramas.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE
: La vista no influirá de forma explícita en la velocidad de fotogramas. Esto significa que, incluso si la vista está activa, el framework no la considerará cuando determine la velocidad de fotogramas.REQUESTED_FRAME_RATE_CATEGORY_NORMAL
: Indica una velocidad de fotogramas media adecuada para animaciones que no requieren velocidades de fotogramas más altas o que no se benefician de una alta fluidez. Por lo general, es de 60 Hz o cerca de ese valor.REQUESTED_FRAME_RATE_CATEGORY_HIGH
: Indica una velocidad de fotogramas adecuada para animaciones que requieren una velocidad alta, lo que puede aumentar la fluidez, pero también el consumo de energía.
Un objeto View vota solo si requiere volver a dibujarse. La velocidad de fotogramas final se determina según el voto más alto. Por ejemplo, si todos los votos son para "Normal", se seleccionará "Normal". Cuando se producen votos de "Normal" y "Alto", se elige "Alto".
Velocidad de fotogramas
Además de las categorías de velocidad de fotogramas, un elemento View también puede especificar una velocidad de fotogramas preferida, como 30, 60 o 120 Hz. Cuando se emiten múltiples votos de velocidad de fotogramas, la velocidad de fotogramas final se determina según las siguientes reglas:
- Múltiples entre sí: Si las velocidades de fotogramas votadas son múltiplos entre sí, se elige el valor más alto. Por ejemplo, si hay dos votos, 30 Hz y 90 Hz, se selecciona 90 Hz como la velocidad de fotogramas final.
- No son múltiplos entre sí:
- Si alguno de los votos es superior a 60 Hz, se cuenta como un voto "Alto".
- Si todos los votos son de 60 Hz o menos, se cuentan como un voto "Normal".
Además, si hay una combinación de valores de velocidad de fotogramas y categorías de velocidad de fotogramas, el valor más alto suele determinar la velocidad de renderización final. Por ejemplo, con una combinación de una votación de 60 Hz y una votación de "Alta", o una votación de 120 Hz y una votación de "Normal", la velocidad de renderización se establecería en 120 Hz.
Además de los votos de una app, también puede haber otros indicadores que se envían a la capa de nivel inferior desde diferentes componentes dentro del mismo marco. Muchos de estos pueden provenir de componentes de la IU del sistema, como la sombra de notificaciones, la barra de estado, la barra de navegación y otros. Los valores de la velocidad de fotogramas final se determinan en función de los votos de varios componentes.
Establece la velocidad de fotogramas o la categoría
En determinadas circunstancias, es posible que tengas una velocidad de fotogramas preferida para una vista. Por ejemplo, puedes establecer la velocidad de fotogramas preferida en "Alta" para que un elemento View aumente la velocidad de fotogramas si una animación no se ve fluida. Además, si hay una animación lenta o estática sobre un video (por lo general, se reproduce a 24 o 30 Hz), es posible que prefieras que la animación se ejecute a una velocidad inferior a "Normal" para reducir el consumo de energía.
Puedes usar las APIs de setRequestedFrameRate()
y getRequestedFrameRate()
para designar la velocidad de fotogramas o la categoría preferida de una vista determinada.
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);
Para ver un ejemplo de uso, consulta TextureView
.
Política general de ARR
En la sección anterior, mencionamos que la mayoría de las animaciones se muestran a 60 Hz de forma predeterminada, ya que cada View tiene "Normal" establecida como la velocidad de fotogramas preferida. Sin embargo, hay excepciones en las que la velocidad de fotogramas se aumenta a "Alta" para garantizar animaciones más fluidas.
La política general de ARR es la siguiente:
- Aumento de la sensibilidad táctil: Cuando se detecta un evento táctil (
MotionEvent.ACTION_DOWN
), la frecuencia de actualización se aumenta a "Alta" durante un tiempo después de que se suelta el toque para mantener la capacidad de respuesta. - Gestos de deslizamiento: Los gestos de deslizamiento se manejan de manera diferente. La frecuencia de actualización disminuye gradualmente a medida que la velocidad de deslizamiento se ralentiza. Puedes encontrar detalles sobre este comportamiento en la sección Mejora del desplazamiento.
- Inicio de la app y transiciones de ventanas: La frecuencia de actualización también se aumenta durante un tiempo durante el inicio de la app, la inicialización de la ventana y las transiciones de ventanas para garantizar una experiencia visual fluida.
- Animaciones: Las animaciones que involucran movimientos o cambios de tamaño reciben automáticamente una frecuencia de actualización más alta para mejorar la fluidez cuando cambia la posición o el tamaño de una vista.
SurfaceView
yTextureView
: Las velocidades de fotogramas establecidas de forma explícita paraTextureView
ySurfaceView
se respetan y aplican según corresponda.
Habilita y desactiva el aumento de la sensibilidad táctil
Puedes habilitar o inhabilitar el aumento de la sensibilidad táctil a nivel de Window
. De forma predeterminada, cuando un usuario toca la pantalla y levanta el dedo, la velocidad de renderización aumenta durante un tiempo. Las APIs de setFrameRateBoostOnTouchEnabled()
y getFrameRateBoostOnTouchEnabled()
te permiten evitar que aumente la velocidad de renderización cuando se toca un Window
específico.
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()
Mejora del desplazamiento
Un caso de uso clave para optimizar la velocidad de fotogramas de forma dinámica es mejorar la experiencia de desplazamiento (lanzamiento). Muchas aplicaciones dependen en gran medida de que los usuarios deslicen el dedo hacia arriba para ver contenido nuevo. La mejora del desplazamiento de ARR ajusta de forma dinámica la frecuencia de actualización a medida que se ralentiza el gesto de deslizamiento, lo que reduce gradualmente la velocidad de fotogramas. Esto proporciona una renderización más eficiente y, al mismo tiempo, mantiene un desplazamiento fluido.
Esta mejora se aplica específicamente a los componentes de IU desplazables, incluidos ScrollView
, ListView
y GridView
, y es posible que no esté disponible para todas las implementaciones personalizadas.
La función de desplazamiento de ARR está disponible para RecyclerView
y NestedScrollView
. Para habilitar esta función en tu app, actualiza a las versiones más recientes de AndroidX.recyclerview
y AndroidX.core
. Consulta la siguiente tabla para obtener más detalles.
Biblioteca |
Versión |
|
1.4.0 |
|
1.15.0 |
Establece la información de velocidad
Si tienes un componente desplazable personalizado y deseas aprovechar la función de desplazamiento, llama a setFrameContentVelocity()
en cada fotograma mientras realizas un desplazamiento suave o arrastras y sueltas. Consulta el siguiente fragmento de código para ver un ejemplo:
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()
Para obtener más ejemplos, consulta RecyclerView
y ScrollView
. Para establecer correctamente la velocidad, calcula la velocidad del contenido (píxeles por segundo) de forma manual si no se puede obtener la información requerida de Scroller
o OverScroller
.
Ten en cuenta que, si se llama a setFrameContentVelocity()
y getFrameContentVelocity()
en Views que no son componentes desplazables, no tendrán ningún efecto, ya que el movimiento activa automáticamente una velocidad de fotogramas mayor según la política actual.
La información de velocidad es fundamental para ajustar la velocidad de renderización. Por ejemplo, considera el gesto de deslizamiento. Al principio, la velocidad de un lanzamiento puede ser alta, lo que requiere una tasa de renderización más alta para garantizar la fluidez. A medida que avanza el gesto, la velocidad disminuye, lo que permite reducir la velocidad de renderización.
Habilita y desactiva el ARR
El ARR está habilitado de forma predeterminada para mejorar la eficiencia energética. Si bien puedes inhabilitar esta función, no se recomienda, ya que la app consumiría más energía. Considera inhabilitar esta función solo si encuentras problemas que afecten de manera significativa la experiencia del usuario.
Para habilitar o inhabilitar el ARR, usa la API de setFrameRatePowerSavingsBalanced()
en un Window
o la API de isFrameRatePowerSavingsBalanced()
a través de tu archivo styles.xml
.
En el siguiente fragmento, se muestra cómo habilitar o inhabilitar el ARR en 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()
Para inhabilitar ARR a través del archivo styles.xml
, agrega el siguiente elemento a tu estilo en res/values/styles.xml
:
<style name="frameRatePowerSavingsBalancedDisabled">
<item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
</style>