GlanceAppWidget 관리 및 업데이트

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

GlanceAppWidget 상태 관리

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

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

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

애플리케이션 상태 사용

앱 위젯은 수동적이어야 합니다. 각 애플리케이션은 데이터 영역을 관리하고 위젯 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 상태 관리 섹션에 설명된 대로 앱 위젯은 다른 프로세스에서 호스팅됩니다. 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 코루틴을 참고하세요.