GlanceAppWidget 관리 및 업데이트

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

GlanceAppWidget 상태 관리

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

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

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

애플리케이션 상태 사용

앱 위젯은 수동적이어야 합니다. 각 애플리케이션은 데이터 레이어를 관리하고 위젯 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를 다시 만들어 다시 전송해야 합니다.

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

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분마다와 같이 더 자주 업데이트하도록 예약합니다.
  • 브로드캐스트에 응답하여 위젯을 업데이트합니다.

리소스