以降のセクションでは、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
メソッドを呼び出し、context
と glanceId
を指定します。
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 Cloud Messaging(FCM)メッセージやブロードキャストに応答してアプリがすでに更新中のとき。
このような場合は、このガイドで説明されているように update
メソッドを呼び出します。
アプリが起動していない場合、ウィジェットは定期的に更新できます。次に例を示します。
updatePeriodMillis
を使用して、ウィジェットを 30 分に 1 回まで更新します。WorkManager
を使用して、15 分ごとなど、より頻繁な更新をスケジュールします。- ブロードキャストに応じてウィジェットを更新します。
リソース
- Glance でウィジェットを作成する(Codelab)
- Android の未来を築く: ウィジェットの章(動画)