-
Android Jetpack Glance: 위젯에 최신 데이터 전달하기개발/개발 지식 공유 2025. 10. 8. 20:29
Jetpack Glance Widget을 사용하여 할 일 목록(Todo List) 위젯을 홈 화면에 만들었습니다.

저는 앱에서 데이터를 수정했을 때 자동으로 최신 데이터가 위젯에도 반영되기를 원했습니다.
하지만 제대로 된 방식으로 데이터를 제공하지 않는다면 위젯이 업뎃되지 않는 문제가 발생할 수 있습니다.
성공적으로 위젯을 업데이트 하는 방법을 공유하려고 합니다.
위젯에 State 데이터 제공하기
일단 위젯에 데이터를 제공하는 가장 좋은 방법은 Flow<T>.collectAsState() 메서드를 사용하는 것입니다.
class TodoWidget : GlanceAppWidget() { override suspend fun provideGlance(context: Context, id: GlanceId) { provideContent { GlanceTheme { TodoWidgetContent(context) } } } @Composable private fun TodoWidgetContent(context: Context) { val repository = remember { (context.applicationContext as TodoApplication).repository } // getAllTodos()는 Kotlin Room을 사용하며, Flow<List<Todo>> 를 반환하는 함수입니다. val todos by repository.getAllTodos().collectAsState(initial = emptyList()) todos.forEach { todo -> TodoItem(todo = todo) Spacer(modifier = GlanceModifier.size(8.dp)) } } }GlanceAppWidget은 @Composable을 통해 화면을 구성합니다.
@Composable의 리컴포지션은 관찰 가능한 상태 변경을 통해서만 가능합니다.
그러므로 State가 아닌 다른 방식으로 데이터를 아무리 가져와봐야 위젯은 업데이트 되지 않습니다.
데이터가 변경되어야 하는 변수는 collectAsState()를 통해 가져올 수 있도록 합시다.
만약 여러분이 Flow를 매끄럽게 처리해주는 Room 같은 데이터 소스를 사용하지 않는다면, 아래와 같이 편법을 써야 합니다.
https://stackoverflow.com/questions/77088363/android-jetpack-glance-1-0-0-problems-updating-widget
GlanceAppWidget 내부적으로 사용하는 GlanceStateDefinition 과 DataStore 를 override하여, plain object를 flow에 담아 emit하는 방식입니다.
어찌 되었든 GlanceAppWidget이 지원하는 방식으로 데이터를 업뎃하려면 이렇게 State에 담아내야 합니다.
명시적으로 위젯 업데이트하기
그리고 하나 더, 저같은 경우에는 애플리케이션에서 홈 화면으로 나가거나, 백그라운드로 전환될 때마다 위젯을 업데이트 하고자 했습니다.
명시적으로 위젯을 업데이트 하려면 GlanceAppWidget.update() 함수를 사용하면 됩니다.
저는 이를 애플리케이션 레벨의 onStop 라이프사이클에 추가하여 실행되도록 했습니다.
class TodoApplication : Application(), DefaultLifecycleObserver { override fun onCreate() { super<Application>.onCreate() // ... // Observe app lifecycle to trigger widget updates ProcessLifecycleOwner.get().lifecycle.addObserver(this) } override fun onStop(owner: LifecycleOwner) { super.onStop(owner) owner.lifecycleScope.launch { TodoWidget().updateAll(applicationContext) } } }주목해야 할 점은 ProcessLifecycleOwner의 사용입니다.
만약 Activity의 onStop 에서 lifecycleScope.launch 로 코드를 실행하면, 코루틴에 추가된 작업이 실행되기 전에 Activity가 destroy 될 경우 코루틴 작업이 취소되어 버리는 상황이 발생합니다.
onStop 라이프사이클에서 suspend fun 코드의 실행을 최대한 보장하려면 ProcessLifecycle을 이용하도록 합시다.
(물론 프로세스가 완전히 종료되어 버리는 상황에서는 실행이 보장되지 않을 수 있습니다)
참고
GlanceAppWidget: https://developer.android.com/develop/ui/compose/glance/glance-app-widget
Compose 상태: https://developer.android.com/develop/ui/compose/state?hl=ko
ProcessLifecycleOwner: https://developer.android.com/reference/androidx/lifecycle/ProcessLifecycleOwner
'개발 > 개발 지식 공유' 카테고리의 다른 글
라즈베리 파이 홈서버 구축하기 (1) 2025.11.30 Raspberry Pi 5 에서 Docker 사용하기 (0) 2025.10.07