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'인 경우 'Normal'이 선택됩니다. '일반'과 '높음' 투표가 모두 발생하면 '높음'이 선택됩니다.
프레임 속도
프레임 속도 카테고리 외에도 뷰는 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 정책
이전 섹션에서는 각 뷰에 선호 프레임 속도가 'Normal'로 설정되어 있으므로 대부분의 애니메이션이 기본적으로 60Hz로 표시된다고 설명했습니다. 하지만 애니메이션을 더 매끄럽게 만들기 위해 프레임 속도가 '높음'으로 증가하는 예외도 있습니다.
일반적인 ARR 정책은 다음과 같습니다.
- 터치 부스트: 터치 이벤트 (
MotionEvent.ACTION_DOWN
)가 감지되면 터치가 해제된 후 일정 시간 동안 응답성을 유지하기 위해 새로고침 빈도가 '높음'으로 부스트됩니다. - 플링 동작: 플링 동작은 다르게 처리됩니다. 플링 속도가 느려짐에 따라 새로고침 빈도가 점차 감소합니다. 이 동작에 관한 자세한 내용은 스크롤 개선사항 섹션을 참고하세요.
- 앱 실행 및 창 전환: 앱 실행, 창 초기화, 창 전환 중에도 부드러운 시각적 환경을 위해 한동안 새로고침 빈도가 향상됩니다.
- 애니메이션: 움직임이나 크기 변경이 포함된 애니메이션은 뷰의 위치나 크기가 변경될 때 부드러움을 향상하기 위해 더 높은 새로고침 빈도를 자동으로 수신합니다.
SurfaceView
및TextureView
:TextureView
및SurfaceView
에 명시적으로 설정된 프레임 속도가 적용됩니다.
터치 부스트 사용 설정 및 사용 중지
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 스크롤 기능은 RecyclerView
및 NestedScrollView
에서 사용할 수 있습니다. 앱에서 이 기능을 사용 설정하려면 AndroidX.recyclerview
및 AndroidX.core
을 최신 버전으로 업그레이드하세요. 자세한 내용은 다음 표를 참고하세요.
라이브러리 |
버전 |
|
1.4.0 |
|
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()
더 많은 예시는 RecyclerView
및 ScrollView
을 참고하세요. 속도를 올바르게 설정하려면 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>
Compose의 ARR
Compose 1.9에서는 적응형 새로고침 빈도도 지원합니다.
뷰 시스템에서는 setRequestedFrameRate()
메서드를 사용하여 뷰의 특정 프레임 속도를 요청합니다. Compose에서는 새로운 수정자를 사용하여 컴포저블의 프레임 속도를 지정할 수 있습니다. 이 수정자는 setRequestedFrameRate()
와 유사하게 작동하며 양수 프레임 속도 값 (Hz) 또는 사전 정의된 프레임 속도 카테고리 FrameRateCategory
를 허용합니다.
API 서명은 다음과 같습니다.
Modifier.preferredFrameRate(frameRate: Float)
Modifier.preferredFrameRate(frameRateCategory: FrameRateCategory)
아래 스니펫에서는 새 프레임 속도 수정자 (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
를 참고하세요.