Оптимизируйте частоту кадров с помощью адаптивной частоты обновления.

При запуске анимации в Android дисплей часто увеличивает частоту обновления до максимальной, чтобы обеспечить плавность изображения. Для небольших анимаций, таких как индикаторы выполнения и аудиовизуализаторы, такая высокая частота обновления не нужна и приводит к высокому энергопотреблению.

Начиная с Android 15, благодаря функции адаптивной частоты обновления (ARR) устройства с поддержкой этой функции могут уменьшить необходимость в высокой частоте обновления по двум направлениям:

  • Благодаря новым оптимизациям управления частотой кадров платформы приложения могут по умолчанию работать с более низкой частотой кадров и увеличивать ее до высокой только при необходимости.
  • Частота обновления дисплея динамически соответствует скорости отображения контента без рывков.

Хотя большинству приложений ARR будет полезен без каких-либо изменений, при необходимости вы также можете переопределить поведение частоты кадров по умолчанию.

На этой странице описывается следующее:

  • Как определяется частота кадров каждого представления.
  • Общая политика определения ARR частоты кадров.
  • Как можно вручную переопределить поведение частоты кадров по умолчанию.

Механизм голосования View

В системе представлений Android каждое представление в иерархии пользовательского интерфейса может указывать свою предпочтительную частоту кадров. Эти настройки собираются и объединяются для определения итоговой частоты кадров для каждого кадра. Это достигается с помощью механизма голосования, где каждое представление голосует на основе своего атрибута частоты кадров, который может быть категорией или конкретной частотой. Представления обычно голосуют при отрисовке или обновлении. Эти голоса объединяются для определения итоговой частоты кадров, которая затем отправляется на уровень нижнего уровня в качестве подсказки для рендеринга.

В настоящее время большинство представлений по умолчанию используют «нормальную» частоту кадров, которая часто равна 60 Гц. Для более высокой частоты кадров можно использовать специальные API для настройки параметров, при этом система обычно выбирает самую высокую частоту кадров. Подробнее об использовании этих API см. в разделе «Установка частоты кадров или категории» . Общие политики, касающиеся частоты кадров, описаны в разделе «Общая политика ARR» .

Категории частоты кадров

В классе View существуют различные категории частоты кадров, которые можно использовать при голосовании. Описание каждой категории приведено ниже:

  • REQUESTED_FRAME_RATE_CATEGORY_DEFAULT : это значение можно установить для возврата к поведению по умолчанию, указывающему, что у этого представления нет данных о частоте кадров.
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE : Вид явно не влияет на частоту кадров. Это означает, что даже если вид активен, фреймворк не будет учитывать его при определении частоты кадров.
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL : Указывает среднюю частоту кадров, подходящую для анимаций, которым не требуется более высокая частота кадров или высокая плавность нежелательна. Обычно это 60 Гц или близко к этому значению.
  • REQUESTED_FRAME_RATE_CATEGORY_HIGH : Указывает частоту кадров, подходящую для анимаций, требующих высокой частоты кадров, что может повысить плавность, но также может увеличить энергопотребление.

Представление голосует только в том случае, если требуется перерисовка. Окончательная частота кадров определяется наибольшим числом голосов. Например, если все голоса отданы за «Нормальный», выбирается вариант «Нормальный». Если есть голоса и за «Нормальный», и за «Высокий», выбирается вариант «Высокий».

Частота кадров

Помимо категорий частоты кадров, представление может также указывать предпочтительную частоту кадров, например, 30, 60 или 120 Гц. При голосовании за несколько частот кадров окончательная частота определяется по следующим правилам:

  • Кратные друг другу : если выбранные частоты кадров кратны друг другу, выбирается наибольшее значение. Например, если выбраны два значения — 30 Гц и 90 Гц, — в качестве окончательной частоты кадров выбирается 90 Гц.
  • Не кратны друг другу :
    • Если какой-либо из голосов превышает 60 Гц, он считается «высоким» голосом.
    • Если все голоса имеют частоту 60 Гц или ниже, это считается «нормальным» голосом.

Кроме того, если используется комбинация значений частоты кадров и категорий частоты кадров, более высокое значение обычно определяет итоговую частоту рендеринга. Например, при сочетании значений 60 Гц и «Высокая» частота рендеринга или 120 Гц и «Нормальная» частота рендеринга обычно устанавливается равной 120 Гц.

Помимо голосов от приложения, на нижний уровень могут быть отправлены и другие подсказки от различных компонентов в пределах одного кадра. Многие из них могут исходить от компонентов системного пользовательского интерфейса, таких как панель уведомлений, строка состояния, панель навигации и другие. Окончательные значения частоты кадров определяются на основе голосов от нескольких компонентов.

Установите частоту кадров или категорию

При определённых обстоятельствах для представления может быть задана предпочтительная частота кадров. Например, можно установить для представления значение «Высокая», чтобы увеличить частоту кадров, если анимация выглядит неплавной. Кроме того, если на видео присутствует медленная или статичная анимация (обычно воспроизводимая с частотой 24 или 30 Гц), можно выбрать частоту кадров ниже «Нормальной» для снижения энергопотребления.

Вы можете использовать API setRequestedFrameRate() и getRequestedFrameRate() для указания предпочтительной частоты кадров или категории данного представления.

Котлин

// 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

Ява

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

Пример использования см. в TextureView .

Общая политика ARR

В предыдущем разделе мы обсуждали, что большинство анимаций по умолчанию отображаются с частотой 60 Гц, поскольку для каждого представления установлена предпочтительная частота кадров «Normal». Однако существуют исключения, когда частота кадров увеличивается до «High» для обеспечения более плавной анимации.

Общая политика ARR выглядит следующим образом:

  • Усиление прикосновения : при обнаружении события прикосновения ( MotionEvent.ACTION_DOWN ) частота обновления увеличивается до «Высокого» на некоторое время после прекращения прикосновения, чтобы сохранить скорость реагирования.
  • Жесты броска : Жесты броска обрабатываются иначе — частота обновления постепенно уменьшается по мере снижения скорости броска. Подробнее об этом поведении можно узнать в разделе «Улучшение прокрутки» .
  • Запуск приложений и переходы окон : частота обновления также увеличивается на некоторое время во время запуска приложений, инициализации окон и переходов окон, чтобы обеспечить плавность визуального восприятия.
  • Анимации : Анимации, включающие движение или изменение размера, автоматически получают более высокую частоту обновления для повышения плавности при изменении положения или размера представления.
  • SurfaceView и TextureView : частоты кадров, явно заданные для TextureView и SurfaceView учитываются и применяются соответствующим образом.

Включить и отключить усиление прикосновений

Вы можете включить и/или отключить усиление сенсорного ввода на уровне Window . По умолчанию, когда пользователь касается экрана и убирает палец с него, скорость отрисовки увеличивается на некоторое время. API setFrameRateBoostOnTouchEnabled() и getFrameRateBoostOnTouchEnabled() позволяют предотвратить увеличение скорости отрисовки при касании определенного Window .

Котлин

// 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

Ява

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

Улучшение прокрутки

Одним из ключевых вариантов использования динамической оптимизации частоты кадров является улучшение качества прокрутки (перелистывания). Многие приложения активно используют свайпы вверх для просмотра нового контента. Улучшение прокрутки ARR динамически корректирует частоту обновления по мере замедления движения, постепенно снижая частоту кадров. Это обеспечивает более эффективную визуализацию при сохранении плавности прокрутки.

Это улучшение применяется конкретно к прокручиваемым компонентам пользовательского интерфейса, включая ScrollView , ListView и GridView , и может быть недоступно для всех пользовательских реализаций.

Функция прокрутки ARR доступна для RecyclerView и NestedScrollView . Чтобы включить эту функцию в вашем приложении, обновите AndroidX.recyclerview и AndroidX.core до последних версий. Подробности см. в таблице ниже.

Библиотека

Версия

AndroidX.recyclerview

1.4.0

AndroidX.core

1.15.0

Установите информацию о скорости

Если у вас есть собственный прокручиваемый компонент и вы хотите воспользоваться его функцией, вызывайте setFrameContentVelocity() для каждого кадра во время плавной прокрутки или перелистывания. Пример см. в следующем фрагменте кода:

Котлин

// set the velocity to a View (1000 pixels/Second)
view.frameContentVelocity = 1000f
// get the velocity of a View
val velocity = view.frameContentVelocity

Ява

// set the velocity to a View
view.setFrameContentVelocity(velocity);

// get the velocity of a View
final float velocity = view.getFrameContentVelocity()

Дополнительные примеры см. в RecyclerView и ScrollView . Чтобы правильно настроить скорость, рассчитайте скорость контента (в пикселях в секунду) вручную, если необходимую информацию невозможно получить от Scroller или OverScroller .

Обратите внимание, что если setFrameContentVelocity() и getFrameContentVelocity() вызываются для представлений, которые не являются прокручиваемыми компонентами, они не дадут никакого эффекта, поскольку движение автоматически приводит к увеличению частоты кадров на основе текущей политики.

Информация о скорости критически важна для настройки скорости рендеринга. Например, рассмотрим жест «бросок». Вначале скорость броска может быть высокой, что требует более высокой скорости рендеринга для обеспечения плавности. По мере развития жеста скорость уменьшается, что позволяет снизить скорость рендеринга.

Включить и отключить ARR

Функция ARR включена по умолчанию для повышения энергоэффективности. Хотя эту функцию можно отключить, делать этого не рекомендуется, так как приложение будет потреблять больше энергии. Отключение этой функции рекомендуется только в случае возникновения проблем, существенно влияющих на удобство использования.

Чтобы включить или отключить ARR, используйте API setFrameRatePowerSavingsBalanced() в Window или API isFrameRatePowerSavingsBalanced() через файл styles.xml .

В следующем фрагменте показано, как включить или отключить ARR в Window :

Котлин

// 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

Ява

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

Чтобы отключить ARR через файл styles.xml , добавьте следующий элемент в свой стиль в res/values/styles.xml :

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

ARR для Compose

В Compose 1.9 также добавлена поддержка адаптивной частоты обновления. В системе View используется метод setRequestedFrameRate() для запроса определённой частоты кадров для View. В Compose появился новый модификатор, позволяющий указать частоту кадров для компонуемого объекта. Этот модификатор работает аналогично setRequestedFrameRate() , принимая либо положительное значение частоты кадров (в Гц), либо предопределённую категорию частоты кадров FrameRateCategory .

Сигнатуры для API следующие:

В приведенном ниже фрагменте кода новый модификатор частоты кадров (Modifier.requestedFrameRate(120f)) применяется к Text компоновщику. Этот модификатор заставляет Text компоновщик запрашивать предпочтительную частоту кадров 120 при отрисовке или анимации (например, при изменении непрозрачности):

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

Предпочтительные частоты кадров для всех компонуемых объектов затем собираются и объединяются для определения итоговой частоты кадров для каждого кадра. Подробнее см. SetFrameRateSample и SetFrameRateCategorySample .