자동 조절 새로고침 빈도로 프레임 속도 최적화

Android에서 애니메이션이 시작되면 디스플레이는 원활한 환경을 보장하기 위해 최대 새로고침 빈도로 증가하는 경우가 많습니다. 진행률 표시줄 및 오디오 시각화 도구와 같은 작은 애니메이션의 경우 이러한 높은 주사율은 필요하지 않으며 전력 소모가 많습니다.

Android 15부터 적응형 재생 빈도 (ARR) 기능을 사용 설정한 기기는 다음 두 가지 측면에서 높은 재생 빈도 레지던시를 줄일 수 있습니다.

  • 새로운 플랫폼 프레임 속도 관리 최적화를 통해 앱은 기본적으로 더 낮은 프레임 속도로 렌더링하고 필요한 경우에만 높은 프레임 속도로 높일 수 있습니다.
  • 디스플레이 새로고침 빈도가 버벅거림 없이 콘텐츠 렌더링 속도에 동적으로 일치합니다.

대부분의 앱은 수정 없이도 ARR의 이점을 누릴 수 있지만, 필요한 경우 기본 프레임 속도 동작을 재정의할 수도 있습니다.

이 페이지에서는 다음 사항을 설명합니다.

  • 각 뷰의 프레임 속도가 결정되는 방식입니다.
  • ARR이 프레임 속도를 설정하는 방법에 관한 일반적인 정책입니다.
  • 기본 프레임 속도 동작을 수동으로 재정의하는 방법

보기 투표 메커니즘

Android의 뷰 시스템에서 UI 계층 구조의 각 뷰는 선호하는 프레임 속도를 표현할 수 있습니다. 이러한 환경설정은 수집되고 결합되어 각 프레임의 최종 프레임 속도를 결정합니다. 이는 각 뷰가 카테고리 또는 특정 속도일 수 있는 프레임 속도 속성을 기반으로 투표하는 투표 메커니즘을 통해 이루어집니다. 뷰는 일반적으로 그려지거나 업데이트될 때 투표합니다. 이러한 투표는 결합되어 최종 프레임 속도를 결정하고, 이는 렌더링 힌트로 하위 레이어로 전송됩니다.

현재 대부분의 뷰는 기본적으로 '일반' 프레임 속도로 설정되며, 이는 60Hz로 설정되는 경우가 많습니다. 더 높은 프레임 속도의 경우 특정 API를 사용하여 환경설정을 맞춤설정할 수 있으며, 시스템은 일반적으로 가장 높은 프레임 속도를 선택합니다. 이러한 API 사용에 관한 자세한 내용은 프레임 속도 또는 카테고리 설정 섹션을 참고하세요. 프레임 속도와 관련된 일반 정책은 일반 ARR 정책 섹션에 설명되어 있습니다.

프레임 속도 카테고리

View 클래스에는 투표에 사용할 수 있는 다양한 프레임 속도 카테고리가 있습니다. 각 카테고리에 대한 설명은 다음과 같습니다.

  • REQUESTED_FRAME_RATE_CATEGORY_DEFAULT: 이 값을 기본 동작으로 돌아가도록 설정할 수 있습니다. 이는 이 뷰에 프레임 속도 데이터가 없음을 나타냅니다.
  • REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE: 뷰가 프레임 속도에 명시적으로 영향을 미치지 않습니다. 즉, 뷰가 활성 상태이더라도 프레임 속도를 결정할 때 프레임워크는 이를 고려하지 않습니다.
  • REQUESTED_FRAME_RATE_CATEGORY_NORMAL: 더 높은 프레임 속도가 필요하지 않거나 높은 부드러움의 이점을 얻지 못하는 애니메이션에 적합한 중간 프레임 속도를 나타냅니다. 일반적으로 60Hz 또는 그와 비슷합니다.
  • REQUESTED_FRAME_RATE_CATEGORY_HIGH: 높은 프레임 속도가 필요한 애니메이션에 적합한 프레임 속도를 나타냅니다. 이 속도는 부드러움을 높일 수 있지만 전력 사용량도 증가시킬 수 있습니다.

뷰는 다시 그려야 하는 경우에만 투표합니다. 최종 프레임 속도는 가장 많은 득표수를 얻은 옵션에 따라 결정됩니다. 예를 들어 모든 투표가 '일반'에 해당하는 경우 '일반'이 선택됩니다. 'Normal'(일반)과 'High'(높음) 투표가 모두 발생하면 'High'(높음)가 선택됩니다.

프레임 속도

뷰는 프레임 속도 카테고리 외에도 30, 60, 120Hz와 같은 기본 프레임 속도를 지정할 수도 있습니다. 여러 프레임 속도에 투표하면 최종 프레임 속도는 다음 규칙에 따라 결정됩니다.

  • 서로의 배수: 투표된 프레임 속도가 서로의 배수인 경우 가장 큰 값이 선택됩니다. 예를 들어 30Hz와 90Hz의 두 가지 투표가 있는 경우 90Hz가 최종 프레임 속도로 선택됩니다.
  • 서로의 배수가 아님:
    • 투표 중 60Hz를 초과하는 투표는 '높음' 투표로 집계됩니다.
    • 모든 투표가 60Hz 이하인 경우 '일반' 투표로 집계됩니다.

또한 프레임 속도 값과 프레임 속도 카테고리가 모두 조합된 경우 일반적으로 더 높은 값이 최종 렌더링 속도를 결정합니다. 예를 들어 60Hz 투표와 '높음' 투표 또는 120Hz 투표와 '일반' 투표가 조합된 경우 렌더링 속도는 일반적으로 120Hz로 설정됩니다.

앱의 투표 외에도 동일한 프레임 내의 다른 구성요소에서 하위 레이어로 전송되는 다른 힌트가 있을 수 있습니다. 이러한 알림 중 다수는 알림 창, 상태 표시줄, 탐색 메뉴와 같은 시스템 UI 구성요소에서 발생할 수 있습니다. 최종 프레임 속도 값은 여러 구성요소의 투표를 기반으로 결정됩니다.

프레임 속도 또는 카테고리 설정

경우에 따라 뷰에 기본 프레임 속도가 있을 수 있습니다. 예를 들어 애니메이션이 원활하지 않은 경우 뷰의 기본 프레임 속도를 '높음'으로 설정하여 프레임 속도를 높일 수 있습니다. 또한 동영상에 느린 애니메이션이나 정적 애니메이션이 있는 경우 (일반적으로 24Hz 또는 30Hz로 재생됨) 전원 소모를 줄이기 위해 애니메이션이 '일반'보다 낮은 속도로 실행되도록 하는 것이 좋습니다.

setRequestedFrameRate()getRequestedFrameRate() API를 사용하여 특정 뷰의 기본 프레임 속도 또는 카테고리를 지정할 수 있습니다.

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

자바

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

이전 섹션에서는 각 뷰의 기본 프레임 속도가 '일반'으로 설정되어 있으므로 대부분의 애니메이션이 기본적으로 60Hz로 표시된다고 설명했습니다. 하지만 애니메이션을 더 원활하게 하기 위해 프레임 속도가 '높음'으로 증가하는 예외도 있습니다.

일반적인 ARR 정책은 다음과 같습니다.

  • 터치 부스트: 터치 이벤트 (MotionEvent.ACTION_DOWN)가 감지되면 터치가 해제된 후 일정 시간 동안 반응성을 유지하기 위해 새로고침 빈도가 '높음'으로 높아집니다.
  • 플링 동작: 플링 동작은 다르게 처리됩니다. 플링 속도가 느려질수록 새로고침 빈도가 점진적으로 감소합니다. 이 동작에 관한 자세한 내용은 스크롤 개선 섹션을 참고하세요.
  • 앱 실행 및 창 전환: 앱 실행, 창 초기화, 창 전환 중에 잠시 화면 새로고침 빈도가 높아져 원활한 시각적 환경을 보장합니다.
  • 애니메이션: 이동 또는 크기 변경이 포함된 애니메이션은 뷰의 위치 또는 크기가 변경될 때 부드러움을 개선하기 위해 자동으로 더 높은 새로고침 빈도를 수신합니다.
  • SurfaceViewTextureView: TextureViewSurfaceView에 명시적으로 설정된 프레임 속도가 적절하게 적용됩니다.

터치 부스트 사용 설정 및 중지

Window 수준에서 터치 부스트를 사용 설정 또는 중지할 수 있습니다. 기본적으로 사용자가 화면을 터치하고 손가락을 떼면 잠시 동안 렌더링 속도가 증가합니다. setFrameRateBoostOnTouchEnabled()getFrameRateBoostOnTouchEnabled() API를 사용하면 특정 Window이 터치될 때 렌더링 속도가 증가하지 않도록 할 수 있습니다.

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

자바

// 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를 비롯한 스크롤 가능한 UI 구성요소에 적용되며 일부 맞춤 구현에서는 사용할 수 없습니다.

ARR 스크롤 기능은 RecyclerViewNestedScrollView에서 사용할 수 있습니다. 앱에서 이 기능을 사용 설정하려면 AndroidX.recyclerviewAndroidX.core의 최신 버전으로 업그레이드하세요. 자세한 내용은 다음 표를 참고하세요.

라이브러리

버전

AndroidX.recyclerview

1.4.0

AndroidX.core

1.15.0

속도 정보 설정

맞춤 스크롤 가능한 구성요소가 있고 스크롤 기능을 활용하려면 부드러운 스크롤 또는 플링 중에 모든 프레임에서 setFrameContentVelocity()를 호출합니다. 예를 보려면 다음 코드 스니펫을 참고하세요.

Kotlin

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

더 많은 예는 RecyclerViewScrollView를 참고하세요. 속도를 올바르게 설정하려면 필요한 정보를 Scroller 또는 OverScroller에서 가져올 수 없는 경우 콘텐츠 속도 (초당 픽셀)를 수동으로 계산합니다.

스크롤 가능한 구성요소가 아닌 뷰에서 setFrameContentVelocity()getFrameContentVelocity()이 호출되면 움직임이 현재 정책에 따라 프레임 속도 증가를 자동으로 트리거하므로 아무런 효과가 없습니다.

속도 정보는 렌더링 속도를 조정하는 데 중요합니다. 예를 들어 플링 동작을 고려해 보겠습니다. 처음에는 플링의 속도가 높을 수 있으므로 부드러운 화면을 보장하기 위해 더 높은 렌더링 속도가 필요합니다. 동작이 진행되면 속도가 감소하여 렌더링 속도를 낮출 수 있습니다.

ARR 사용 설정 및 중지

ARR은 전원 효율성을 높이기 위해 기본적으로 사용 설정되어 있습니다. 이 기능을 사용 중지할 수 있지만 앱에서 더 많은 전력을 소비하므로 권장하지 않습니다. 사용자 환경에 상당한 영향을 미치는 문제가 발생한 경우에만 이 기능을 사용 중지하는 것이 좋습니다.

ARR을 사용 설정하거나 중지하려면 Window에서 setFrameRatePowerSavingsBalanced() API를 사용하거나 styles.xml 파일을 통해 isFrameRatePowerSavingsBalanced() API를 사용하세요.

다음 스니펫은 Window에서 ARR을 사용 설정하거나 사용 중지하는 방법을 보여줍니다.

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

자바

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

styles.xml 파일을 통해 ARR을 사용 중지하려면 res/values/styles.xml의 스타일에 다음 항목을 추가합니다.

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