GlanceAppWidget 관리 및 업데이트

다음 섹션에서는 GlanceAppWidget을 업데이트하고 상태를 관리하는 방법을 설명합니다.

GlanceAppWidget 상태 관리

제공된 GlanceAppWidget 클래스는 위젯이 생성되거나 업데이트가 필요할 때마다 인스턴스화되므로 스테이트리스 및 수동 이어야 합니다.

상태 개념은 다음과 같이 나눌 수 있습니다.

  • 애플리케이션 상태: 위젯에 필요한 앱의 상태 또는 콘텐츠입니다. 예를 들어 사용자가 정의한 저장된 대상 목록 (즉, 데이터베이스)입니다.
  • Glance 상태: 앱 위젯과만 관련이 있고 앱의 상태를 수정하거나 영향을 미치지 않는 특정 상태입니다. 예를 들어 위젯에서 체크박스가 선택되었거나 카운터가 증가했습니다.

애플리케이션 상태 사용

앱 위젯은 수동이어야 합니다. 각 애플리케이션은 데이터 레이어를 관리하고 위젯 UI에 반영된 유휴, 로드, 오류와 같은 상태를 처리합니다.

예를 들어 다음 코드는 저장소 레이어의 메모리 내 캐시에서 대상을 가져오고 저장된 대상 목록을 제공하며 상태에 따라 다른 UI를 표시합니다.

class DestinationAppWidget : GlanceAppWidget() {

    // ...

    @Composable
    fun MyContent() {
        val repository = remember { DestinationsRepository.getInstance() }
        // Retrieve the cache data everytime the content is refreshed
        val destinations by repository.destinations.collectAsState(State.Loading)

        when (destinations) {
            is State.Loading -> {
                // show loading content
            }

            is State.Error -> {
                // show widget error content
            }

            is State.Completed -> {
                // show the list of destinations
            }
        }
    }
}

상태 또는 데이터가 변경될 때마다 앱이 위젯에 알리고 업데이트해야 합니다. 자세한 내용은 GlanceAppWidget 업데이트를 참고하세요.

GlanceAppWidget 업데이트

GlanceAppWidget을 사용하여 위젯 콘텐츠 업데이트를 요청할 수 있습니다. 관리GlanceAppWidget 상태 섹션에서 설명한 대로 앱 위젯은 다른 프로세스에서 호스팅됩니다. Glance는 콘텐츠를 실제 RemoteViews로 변환하고 호스트로 전송합니다. 콘텐츠를 업데이트하려면 Glance가 RemoteViews를 다시 만들고 다시 전송해야 합니다.

업데이트를 전송하려면 context 및 glanceId를 제공하여 GlanceAppWidget 인스턴스의 update 메서드를 호출합니다.

MyAppWidget().update(context, glanceId)

glanceId를 가져오려면 GlanceAppWidgetManager를 쿼리합니다.

val manager = GlanceAppWidgetManager(context)
val widget = GlanceSizeModeWidget()
val glanceIds = manager.getGlanceIds(widget.javaClass)
glanceIds.forEach { glanceId ->
    widget.update(context, glanceId)
}

또는 GlanceAppWidget update 확장 프로그램 중 하나를 사용합니다.

// Updates all placed instances of MyAppWidget
MyAppWidget().updateAll(context)

// Iterate over all placed instances of MyAppWidget and update if the state of
// the instance matches the given predicate
MyAppWidget().updateIf<State>(context) { state ->
    state == State.Completed
}

이러한 메서드는 애플리케이션의 어느 부분에서나 호출할 수 있습니다. suspend 함수이므로 기본 스레드 범위 외부에서 실행하는 것이 좋습니다. 다음 예에서는 CoroutineWorker에서 실행됩니다.

class DataSyncWorker(
    val context: Context,
    val params: WorkerParameters,
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        // Fetch data or do some work and then update all instance of your widget
        MyAppWidget().updateAll(context)
        return Result.success()
    }
}

코루틴에 관한 자세한 내용은 Android의 Kotlin 코루틴을 참고하세요.

위젯을 업데이트하는 시점

위젯을 즉시 또는 주기적으로 업데이트합니다.

앱이 활성 상태일 때 위젯을 즉시 업데이트할 수 있습니다. 예를 들면 다음과 같습니다.

  • 사용자가 위젯과 상호작용하여 작업, 람다 호출 또는 활동을 실행하는 인텐트를 트리거하는 경우
  • 사용자가 포그라운드에서 앱과 상호작용하거나 앱이 이미 Firebase 클라우드 메시징 (FCM) 메시지 또는 브로드캐스트에 응답하여 업데이트하는 동안

이러한 경우 이 가이드에 설명된 대로 update 메서드를 호출합니다.

앱이 활성 상태가 아닐 때 위젯을 주기적으로 업데이트할 수 있습니다. 예를 들면 다음과 같습니다.

  • updatePeriodMillis를 사용하여 최대 30 분마다 한 번씩 위젯을 업데이트합니다.
  • WorkManager를 사용하여 15분마다와 같이 더 자주 업데이트하도록 예약합니다.
  • 브로드캐스트에 응답하여 위젯을 업데이트합니다.

리소스