오늘 Jetpack Compose 2025년 12월 출시가 안정화되었습니다. 여기에는 핵심 Compose 모듈 버전 1.10과 Material 3 버전 1.4가 포함되어 새로운 기능과 주요 성능 개선사항이 추가됩니다 (전체 BOM 매핑 참고).
오늘 출시된 버전을 사용하려면 Compose BOM 버전을 2025.12.00로 업그레이드하세요.
implementation(platform("androidx.compose:compose-bom:2025.12.00"))
성능 개선
앱의 런타임 성능은 개발자와 사용자에게 매우 중요하므로 Compose팀은 성능을 최우선으로 고려해 왔습니다. 이번 출시에는 여러 개선사항이 포함되어 있으며 최신 버전으로 업그레이드하면 이러한 개선사항을 모두 이용할 수 있습니다. 내부 스크롤 벤치마크에 따르면 이제 Compose가 뷰를 사용하는 경우와 동일한 성능을 보입니다.
다양한 Compose 버전에서 뷰와 Jetpack Compose를 비교하는 스크롤 성능 벤치마크
지연 미리 가져오기에서 일시중지 가능한 컴포지션
지연 미리 가져오기에서 일시중지 가능한 컴포지션이 이제 기본적으로 사용 설정됩니다. 이는 Compose 런타임이 작업을 예약하는 방식에 대한 근본적인 변경사항으로, 과도한 UI 워크로드 중에 발생하는 끊김 현상을 크게 줄이도록 설계되었습니다.
이전에는 컴포지션이 시작되면 완료될 때까지 실행해야 했습니다. 컴포지션이 복잡한 경우 단일 프레임보다 오래 기본 스레드를 차단하여 UI가 정지될 수 있습니다. 일시중지 가능한 컴포지션을 사용하면 시간이 부족한 경우 런타임이 작업을 '일시중지'하고 다음 프레임에서 작업을 재개할 수 있습니다. 이는 지연된 레이아웃 프리패치와 함께 사용하여 프레임을 미리 준비할 때 특히 효과적입니다. Compose 1.9에 도입된 지연 레이아웃 CacheWindow API는 더 많은 콘텐츠를 미리 가져오고 일시중지 가능한 컴포지션의 이점을 활용하여 훨씬 더 부드러운 UI 성능을 구현할 수 있는 좋은 방법입니다.
일시중지 가능한 컴포지션을 지연 로드 프리패치와 결합하면 끊김 현상을 줄일 수 있습니다
또한 Modifier.onPlaced, Modifier.onVisibilityChanged 및 기타 수정자 구현을 개선하여 다른 곳에서도 성능을 최적화했습니다. Google은 Compose의 성능을 개선하기 위해 계속 투자할 예정입니다.
새로운 기능
유지
Compose는 다양한 수명 주기에서 상태를 유지하고 관리하는 여러 API를 제공합니다. 예를 들어 remember는 컴포지션 전반에 걸쳐 상태를 유지하고 rememberSavable/rememberSerializable는 활동 또는 프로세스 재생성 전반에 걸쳐 상태를 유지합니다. retain은 이러한 API 사이에 있는 새로운 API로, 직렬화되지 않고 구성 변경 전반에 값을 유지할 수 있지만 프로세스 종료 전반에는 유지할 수 없습니다. retain는 상태를 직렬화하지 않으므로 쉽게 직렬화할 수 없는 람다 표현식, 흐름, 비트맵과 같은 대형 객체를 유지할 수 있습니다. 예를 들어 retain를 사용하여 미디어 플레이어 (예: ExoPlayer)를 관리하여 구성 변경으로 인해 미디어 재생이 중단되지 않도록 할 수 있습니다.
@Composable fun MediaPlayer() { val applicationContext = LocalContext.current.applicationContext val exoPlayer = retain { ExoPlayer.Builder(applicationContext).apply { ... }.build() } ... }
이 기능의 설계에 영향을 주고 기여한 AndroidDev 커뮤니티 (특히 Circuit팀)에 감사의 말씀을 전합니다.
Material 1.4
material3 라이브러리 버전 1.4.0에는 다음과 같은 새로운 구성요소와 개선사항이 추가되었습니다.
- 이제
TextField는 텍스트 상태를 관리하는 더 강력한 방법을 제공하는 실험용TextFieldState기반 버전을 제공합니다. 또한 새로운SecureTextField및OutlinedSecureTextField변형이 제공됩니다. 이제 materialText컴포저블이 autoSize 동작을 지원합니다. - 이제 캐러셀 구성요소에서 새로운
HorizontalCenteredHeroCarousel변형을 제공합니다. - 이제
TimePicker에서 선택 도구와 입력 모드 간 전환을 지원합니다. - 세로 드래그 핸들을 사용하면 사용자가 적응형 창의 크기나 위치를 변경할 수 있습니다.
가로 중앙 영웅 캐러셀
Material 3 Expressive API는 material3 라이브러리의 알파 버전에서 계속 개발됩니다. 자세한 내용은 다음 최근 강연을 참고하세요.
새로운 애니메이션 기능
공유 요소 애니메이션 맞춤설정 업데이트를 비롯해 애니메이션 API를 계속 확장하고 있습니다.
동적 공유 요소
기본적으로 sharedElement() 및 sharedBounds() 애니메이션은
일치하는 키가 타겟 상태에서 발견될 때마다 레이아웃이 변경됩니다. 하지만 탐색 방향이나 현재 UI 상태와 같은 특정 조건에 따라 이 애니메이션을 동적으로 사용 중지할 수 있습니다.
공유 요소 전환이 발생하는지 여부를 제어하려면 이제 rememberSharedContentState()에 전달되는 SharedContentConfig를 맞춤설정하면 됩니다. isEnabled 속성은 공유 요소가 활성 상태인지 여부를 결정합니다.
SharedTransitionLayout {
val transition = updateTransition(currentState)
transition.AnimatedContent { targetState ->
// Create the configuration that depends on state changing.
fun animationConfig() : SharedTransitionScope.SharedContentConfig {
return object : SharedTransitionScope.SharedContentConfig {
override val SharedTransitionScope.SharedContentState.isEnabled: Boolean
get() =
// determine whether to perform a shared element transition
}
}
}자세한 내용은 문서를 참고하세요.
Modifier.skipToLookaheadPosition()
이 출시에는 공유 요소 애니메이션을 실행할 때 컴포저블의 최종 위치를 유지하는 새로운 수정자 Modifier.skipToLookaheadPosition()가 추가되었습니다. 이를 통해 카메라의 점진적 공개와 같이 Androidify 샘플에서 볼 수 있는 '공개' 유형 애니메이션과 같은 전환을 실행할 수 있습니다. 자세한 내용은 여기에서 동영상 도움말을 참고하세요.
공유 요소 전환의 초기 속도
이 출시에서는 공유 요소 전환에 초기 속도 (예: 동작에서)를 전달할 수 있는 새로운 공유 요소 전환 API인 prepareTransitionWithInitialVelocity를 추가합니다.
Modifier.fillMaxSize()
.draggable2D(
rememberDraggable2DState { offset += it },
onDragStopped = { velocity ->
// Set up the initial velocity for the upcoming shared element
// transition.
sharedContentStateForDraggableCat
?.prepareTransitionWithInitialVelocity(velocity)
showDetails = false
},
)
동작의 초기 속도로 시작하는 공유 요소 전환
베일 전환
EnterTransition 및 ExitTransition는 AnimatedVisibility/AnimatedContent 컴포저블이 표시되거나 사라지는 방식을 정의합니다. 새로운 실험용 베일 옵션을 사용하면 콘텐츠를 가리거나 스크림할 색상을 지정할 수 있습니다.예를 들어 콘텐츠 위에 반투명 검은색 레이어를 페이드 인/아웃할 수 있습니다.
베일이 적용된 애니메이션 콘텐츠 - 애니메이션 중에 그리드 콘텐츠 위에 반투명 베일 (또는 스크림)이 표시됨
AnimatedContent(
targetState = page,
modifier = Modifier.fillMaxSize().weight(1f),
transitionSpec = {
if (targetState > initialState) {
(slideInHorizontally { it } togetherWith
slideOutHorizontally { -it / 2 } + veilOut(targetColor = veilColor))
} else {
slideInHorizontally { -it / 2 } +
unveilIn(initialColor = veilColor) togetherWith slideOutHorizontally { it }
}
},
) { targetPage ->
...
}예정된 변경사항
Modifier.onFirstVisible 지원 중단
Compose 1.9에서는 Modifier.onVisibilityChanged 및 Modifier.onFirstVisible가 도입되었습니다. 의견을 검토한 결과, Modifier.onFirstVisible 계약을 결정론적으로 준수할 수 없는 것으로 확인되었습니다. 특히 처음 항목이 표시될 때 그렇습니다. 예를 들어 지연 레이아웃은 뷰포트에서 스크롤되는 항목을 삭제한 다음 항목이 다시 뷰로 스크롤되면 다시 구성할 수 있습니다. 이 경우 새로 구성된 항목이므로 onFirstVisible 콜백이 다시 실행됩니다. onFirstVisible가 포함된 이전에 방문한 화면으로 다시 이동할 때도 비슷한 동작이 발생합니다. 따라서 다음 Compose 출시 (1.11)에서 이 수정자를 지원 중단하고 onVisibilityChanged로 이전하는 것이 좋습니다. 자세한 내용은 문서를 참고하세요.
테스트의 코루틴 디스패치
테스트의 코루틴 디스패치를 변경하여 테스트 불안정성을 개선하고 더 많은 문제를 포착할 계획입니다. 현재 테스트에서는 UnconfinedTestDispatcher를 사용하며 이는 프로덕션 동작과 다릅니다. 예를 들어 효과가 대기열에 추가되지 않고 즉시 실행될 수 있습니다. 향후 출시에서는 프로덕션 동작과 일치하도록 기본적으로 StandardTestDispatcher을 사용하는 새 API를 도입할 예정입니다. 1.10에서 지금 새로운 동작을 사용해 볼 수 있습니다.
@get:Rule // also createAndroidComposeRule, createEmptyComposeRule val rule = createComposeRule(effectContext = StandardTestDispatcher())
StandardTestDispatcher를 사용하면 작업이 대기열에 추가되므로 composeTestRule.waitForIdle() 또는 composeTestRule.runOnIdle()와 같은 동기화 메커니즘을 사용해야 합니다. 테스트에서 runTest를 사용하는 경우 runTest와 Compose 규칙이 동기화를 위해 동일한 StandardTestDispatcher 인스턴스를 공유해야 합니다.
// 1. Create a SINGLE dispatcher instance val testDispatcher = StandardTestDispatcher() // 2. Pass it to your Compose rule @get:Rule val composeRule = createComposeRule(effectContext = testDispatcher) @Test // 3. Pass the *SAME INSTANCE* to runTest fun myTest() = runTest(testDispatcher) { composeRule.setContent { /* ... */ } }
도구
훌륭한 API에는 훌륭한 도구가 필요하며 Android 스튜디오에는 Compose 개발자를 위한 최근 추가 기능이 많이 있습니다.
- 변환 UI:
@Preview를 마우스 오른쪽 버튼으로 클릭하고 변환 UI를 선택한 다음 자연어로 변경사항을 설명하여 디자인을 반복합니다. - 생성
@Preview: 컴포저블을 마우스 오른쪽 버튼으로 클릭하고 Gemini > [컴포저블 이름] 미리보기 생성을 선택합니다. - Vector Asset 마법사의 아이콘 변형에 대한 새로운 지원으로 Material Symbols 맞춤설정
- 스크린샷에서 코드를 생성하거나 Gemini에게 기존 UI를 타겟 이미지와 일치시켜 달라고 요청하세요. 이를 원격 MCP 지원과 결합하여 Figma 파일에 연결하고 디자인에서 Compose UI를 생성할 수 있습니다.
- UI 품질 문제 수정은 접근성 문제와 같은 일반적인 문제를 UI에서 감사한 다음 수정사항을 제안합니다.
이러한 도구가 실제로 작동하는 모습을 보려면 최근 데모를 시청하세요.
즐겁게 작성하세요
Google은 멋지고 풍부한 UI를 만드는 데 필요한 API와 도구를 제공하기 위해 Jetpack Compose에 계속 투자하고 있습니다. Google에서는 여러분의 의견을 소중하게 생각합니다. 이러한 변경사항이나 다음에 보고 싶은 기능에 대한 의견을 문제 추적기에 공유해 주세요.
계속 읽기
-
제품 소식
이제 Android Emulator를 사용하면 멀티 디바이스 상호작용을 그 어느 때보다 쉽게 테스트할 수 있습니다.
Steven Jenkins • 전문 길이: 2분
-
제품 소식
모든 개발자의 AI 워크플로와 요구사항은 고유하며, AI가 개발에 어떤 도움을 줄지 선택할 수 있는 것이 중요합니다. 1월에는 Android 스튜디오에서 AI 기능을 구동하는 데 로컬 또는 원격 AI 모델을 선택할 수 있는 기능이 도입되었습니다.
Matthew Warner • 전문 길이: 2분
-
제품 소식
이제 Android 스튜디오 Panda 3가 안정화되어 프로덕션에서 사용할 수 있습니다. 이번 출시를 통해 AI 기반 워크플로를 더욱 세부적으로 제어하고 맞춤설정할 수 있어 고품질 Android 앱을 그 어느 때보다 쉽게 빌드할 수 있습니다.
Matt Dyor • 3분 읽기
소식 받아 보기
Android 개발 관련 최신 정보를 이메일로 받아 보세요.