안드로이드 DreamService: 드림 스크린을 위한 Jetpack Compose 통합
안드로이드 4.2 에서 도입된 DreamService 는 기기가 충전 중이고 대기 상태일 때 커스텀 UI 를 표시할 수 있게 해줍니다. 이 컴포넌트는 Service 를 상속받으며 버튼을 포함한 인터랙티브 요소를 지원합니다. 활성화하려면 디스플레이 설정에서 사용자가 수동으로 구성해야 합니다. 이 솔루션은 메인 앱 라이프사이클에 영향을 주지 않고 동적 스크린을 만드는 데 적합합니다.
AndroidManifest.xml 에 서비스를 선언하는 것은 표준적입니다:
<service
android:name=".MyDreamService"
android:exported="true"
android:description="@string/dream_service_description"
android:icon="@drawable/dream_service_icon"
android:label="@string/dream_service_label"
android:permission="android.permission.BIND_DREAM_SERVICE">
<intent-filter>
<action android:name="android.service.dreams.DreamService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
기본 구현은 뷰를 구성하기 위해 onAttachedToWindow() 를 사용합니다:
class MyDreamService : DreamService() {
override fun onAttachedToWindow() {
super.onAttachedToWindow()
isInteractive = false
isFullscreen = true
setContentView(R.layout.dream_service_layout)
}
}
DreamService 에 Jetpack Compose 통합하기
setContentView 메서드는 Views 와만 작동하므로 Compose 를 위해 ComposeView 를 생성합니다. 그러나 DreamService 는 Compose 가 올바르게 작동하는 데 중요한 ViewTreeLifecycleOwner 와 SavedStateRegistryOwner 를 제공하지 않습니다.
해결책은 SavedStateRegistryOwner 구현으로 DreamService 를 확장하는 것입니다:
class MyDreamService : DreamService(), SavedStateRegistryOwner {
private val lifecycleRegistry = LifecycleRegistry(this)
private val savedStateRegistryController = SavedStateRegistryController.create(this)
override val lifecycle: Lifecycle
get() = lifecycleRegistry
override val savedStateRegistry: SavedStateRegistry
get() = savedStateRegistryController.savedStateRegistry
}
onAttachedToWindow() 에서 라이프사이클과 레지스트리를 동기화합니다:
val composeView = ComposeView(this).apply {
setViewTreeLifecycleOwner(this@MyDreamService)
setViewTreeSavedStateRegistryOwner(this@MyDreamService)
setContent {
DreamServiceTheme {
DreamScreen(
onOpenSettings = {
openSettingsAndExitDream()
}
)
}
}
}
setContentView(composeView)
적절한 상태 동기화를 위해 DreamService 콜백 (onAttachedToWindow, onDetachedFromWindow 등) 에서 lifecycle 메서드를 호출하는 것을 잊지 마세요.
주요 제한 사항 및 모범 사례
- 활성화: 사용자가 설정에서 Daydream 을 수동으로 활성화해야 합니다. 자동 실행은 불가능합니다.
- 라이프사이클: Compose 를 위해
LifecycleOwner를 완전히 구현하세요. 그렇지 않으면 UI 가 업데이트되지 않습니다. - 성능: 기기가 절전 모드이므로 무거운 애니메이션은 피하세요.
- 상호작용:
isInteractive = true는 버튼을 허용하지만 전력 소비에 대해 주의가 필요합니다.
구현 단계 목록:
- 매니페스트에
BIND_DREAM_SERVICE권한으로 서비스를 선언합니다. DreamService를 상속받고SavedStateRegistryOwner를 추가합니다.LifecycleRegistry와SavedStateRegistryController를 초기화합니다.ComposeView에서setContent전에 소유자를 설정합니다.- 충전 모드에서 실제 기기에서 테스트합니다.
주요 요약
- DreamService 는 라이프사이클 조정 후 Compose 를 지원하는 Activity 외의 완전한 UI 호스터입니다.
- 디스플레이 설정에서 수동 활성화는 필수입니다.
- 서비스를 확장하여
ViewTreeLifecycleOwner문제를 해결하세요. - 시계, 알림, 미니 게임 등 대기 화면에 적합합니다.
- 전력 절약이 중요합니다. 드로우 호출을 최소화하세요.
이 기능은 안드로이드 개발 기능을 확장하여 비표준 시나리오에서 기기 동작을 커스터마이징할 수 있게 합니다. 시니어 개발자에게는 플랫폼 서비스와 현대 UI 프레임워크의 통합에 대한 깊은 이해의 맥락에서 유용합니다.
— Editorial Team
아직 댓글이 없습니다.