앱이 해당 AppWidgetProvider 클래스와 동일한 UID를 갖는 한 앱의 어느 곳에서나 이러한 메서드를 호출할 수 있습니다.
위젯 업데이트 빈도 결정
위젯은 updatePeriodMillis 속성에 제공된 값에 따라 주기적으로 업데이트됩니다. 위젯은 사용자 상호작용에 응답하여 업데이트하거나 업데이트를 브로드캐스트하거나 둘 다 할 수 있습니다.
주기적으로 업데이트
appwidget-provider XML에서 AppWidgetProviderInfo.updatePeriodMillis 값을 지정하여 주기적 업데이트의 빈도를 제어할 수 있습니다. 각 업데이트는 AppWidgetProvider.onUpdate() 메서드를 트리거하며, 여기에 위젯을 업데이트하는 코드를 배치할 수 있습니다. 하지만 위젯이 비동기적으로 데이터를 로드해야 하거나 업데이트하는 데 10초 이상 걸리는 경우 다음 섹션에 설명된 브로드캐스트 리시버 업데이트의 대안을 고려하세요. 10초가 지나면 시스템에서 BroadcastReceiver이 응답하지 않는 것으로 간주하기 때문입니다.
updatePeriodMillis은 30분 미만의 값을 지원하지 않습니다. 하지만 주기적인 업데이트를 사용 중지하려면 0을 지정하면 됩니다.
사용자가 구성에서 업데이트 빈도를 조정하도록 할 수 있습니다. 예를 들어 주식 시세를 15분마다 업데이트하고 싶은 사람도 있고 하루에 네 번만 업데이트하고 싶은 사람도 있습니다. 이 경우 updatePeriodMillis을 0으로 설정하고 대신 WorkManager를 사용합니다.
사용자 상호작용에 대한 응답으로 업데이트
다음은 사용자 상호작용에 따라 위젯을 업데이트하는 권장 방법입니다.
앱의 활동에서: 사용자의 탭과 같은 사용자 상호작용에 대한 응답으로 AppWidgetManager.updateAppWidget을 직접 호출합니다.
알림이나 앱 위젯과 같은 원격 상호작용에서:PendingIntent를 구성한 다음 호출된 Activity, Broadcast 또는 Service에서 위젯을 업데이트합니다. 우선순위를 직접 선택할 수 있습니다. 예를 들어 PendingIntent에 Broadcast를 선택하면 BroadcastReceiver에 우선순위를 부여하는 포그라운드 브로드캐스트를 선택할 수 있습니다.
브로드캐스트 이벤트에 대한 응답으로 업데이트
위젯을 업데이트해야 하는 브로드캐스트 이벤트의 예는 사용자가 사진을 찍는 경우입니다. 이 경우 새 사진이 감지되면 위젯을 업데이트해야 합니다.
브로드캐스트용 BroadcastReceiver를 등록할 수도 있습니다(예: ACTION_LOCALE_CHANGED 수신 대기).
하지만 이 기능은 기기 리소스를 사용하므로 주의해서 사용하고 특정 브로드캐스트만 수신하세요. Android 7.0 (API 수준 24) 및 Android 8.0 (API 수준 26)에서 브로드캐스트 제한이 도입됨에 따라 앱은 특정 예외를 제외하고 매니페스트에서 암시적 브로드캐스트를 등록할 수 없습니다.
BroadcastReceiver에서 위젯을 업데이트할 때 고려사항
AppWidgetProvider을 비롯한 BroadcastReceiver에서 위젯을 업데이트하는 경우 위젯 업데이트의 기간 및 우선순위에 관한 다음 고려사항을 참고하세요.
업데이트 기간
일반적으로 시스템은 앱의 기본 스레드에서 실행되는 브로드캐스트 리시버가 응답하지 않는 것으로 간주하고 애플리케이션 응답 없음 (ANR) 오류를 트리거하기 전에 최대 10초 동안 실행되도록 허용합니다. 브로드캐스트를 처리하는 동안 기본 스레드가 차단되지 않도록 하려면 goAsync 메서드를 사용하세요. 위젯을 업데이트하는 데 시간이 오래 걸리는 경우 WorkManager를 사용하여 작업을 예약하는 것이 좋습니다.
기본적으로 AppWidgetProvider.onUpdate을 사용하여 만든 브로드캐스트를 비롯한 브로드캐스트는 백그라운드 프로세스로 실행됩니다. 즉, 과부하된 시스템 리소스로 인해 브로드캐스트 리시버 호출이 지연될 수 있습니다. 브로드캐스트의 우선순위를 지정하려면 포그라운드 프로세스로 만드세요.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-08-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-08-27(UTC)"],[],[],null,["Try the Compose way \nJetpack Compose is the recommended UI toolkit for Android. Learn how to build widgets using Compose-style APIs. \n[Jetpack Glance →](/develop/ui/compose/glance) \n\n\u003cbr /\u003e\n\nThis page explains recommended practices for creating a more advanced widget for\na better user experience.\n\nOptimizations for updating widget content\n\nUpdating widget content can be computationally expensive. To save battery\nconsumption, optimize the update type, frequency, and timing.\n\nTypes of widget updates\n\nThere are three ways to update a widget: a full update, a partial update, and,\nin the case of a collection widget, a data refresh. Each has different\ncomputational costs and ramifications.\n\nThe following describes each update type and provides code snippets for each.\n\n- **Full update:** call [`AppWidgetManager.updateAppWidget(int,\n android.widget.RemoteViews)`](/reference/android/appwidget/AppWidgetManager#updateAppWidget(int,%20android.widget.RemoteViews))\n to fully update the widget. This replaces the previously provided\n [`RemoteViews`](/reference/android/widget/RemoteViews) with a new\n `RemoteViews`. This is the most computationally expensive update.\n\n Kotlin \n\n ```kotlin\n val appWidgetManager = AppWidgetManager.getInstance(context)\n val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also {\n setTextViewText(R.id.textview_widget_layout1, \"Updated text1\")\n setTextViewText(R.id.textview_widget_layout2, \"Updated text2\")\n }\n appWidgetManager.updateAppWidget(appWidgetId, remoteViews)\n ```\n\n Java \n\n ```java\n AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);\n RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);\n remoteViews.setTextViewText(R.id.textview_widget_layout1, \"Updated text1\");\n remoteViews.setTextViewText(R.id.textview_widget_layout2, \"Updated text2\");\n appWidgetManager.updateAppWidget(appWidgetId, remoteViews);\n ```\n- **Partial update:** call\n [`AppWidgetManager.partiallyUpdateAppWidget`](/reference/android/appwidget/AppWidgetManager#partiallyUpdateAppWidget(int,%20android.widget.RemoteViews))\n to update parts of the widget. This merges the new `RemoteViews` with the\n previously provided `RemoteViews`. This method is ignored if a widget\n doesn't receive at least one full update through [`updateAppWidget(int[],\n RemoteViews)`](/reference/android/appwidget/AppWidgetManager#updateAppWidget(android.content.ComponentName,%20android.widget.RemoteViews)).\n\n Kotlin \n\n ```kotlin\n val appWidgetManager = AppWidgetManager.getInstance(context)\n val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also {\n setTextViewText(R.id.textview_widget_layout, \"Updated text\")\n }\n appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)\n ```\n\n Java \n\n ```java\n AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);\n RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);\n remoteViews.setTextViewText(R.id.textview_widget_layout, \"Updated text\");\n appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews);\n ```\n- **Collection data refresh:** call\n [`AppWidgetManager.notifyAppWidgetViewDataChanged`](/reference/android/appwidget/AppWidgetManager#notifyAppWidgetViewDataChanged(int,%20int))\n to invalidate the data of a collection view in your widget. This triggers\n [`RemoteViewsFactory.onDataSetChanged`](/reference/android/widget/RemoteViewsService.RemoteViewsFactory#onDataSetChanged()).\n In the interim, the old data is displayed in the widget. You can safely\n perform expensive tasks synchronously with this method.\n\n Kotlin \n\n ```kotlin\n val appWidgetManager = AppWidgetManager.getInstance(context)\n appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)\n ```\n\n Java \n\n ```java\n AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);\n appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview);\n ```\n\nYou can call these methods from anywhere in your app, as long as the app has the\nsame UID as the corresponding\n[`AppWidgetProvider`](/reference/android/appwidget/AppWidgetProvider) class.\n\nDetermine how often to update a widget\n\nWidgets are updated periodically depending on the value provided for the\n[`updatePeriodMillis`](/reference/android/appwidget/AppWidgetProviderInfo#updatePeriodMillis)\nattribute. The widget can update in response to user interaction, broadcast\nupdates, or both.\n\nUpdate periodically\n\nYou can control the frequency of the periodic update by specifying a value for\n`AppWidgetProviderInfo.updatePeriodMillis` in the `appwidget-provider` XML. Each\nupdate triggers the `AppWidgetProvider.onUpdate()` method, which is where you\ncan place the code to update the widget. However, consider the [alternatives for\nbroadcast receiver updates](#broadcastreceiver-duration) described in a\nfollowing section if your widget needs to load data asynchronously or takes more\nthan 10 seconds to update, because after 10 seconds, the system considers a\n`BroadcastReceiver` to be non-responsive.\n\n`updatePeriodMillis` doesn't support values of less than 30 minutes. However, if\nyou want to disable periodic updates, you can specify 0.\n\nYou can let users adjust the frequency of updates in a configuration. For\nexample, they might want a stock ticker to update every 15 minutes or only four\ntimes a day. In this case, set the `updatePeriodMillis` to 0 and use\n[`WorkManager`](/topic/libraries/architecture/workmanager) instead.\n| **Note:** Using repeating tasks with `WorkManager` is a good option, but similar power restrictions apply. See [App Standby\n| Buckets](/about/versions/pie/power#buckets) for more information.\n\nUpdate in response to a user interaction\n\nHere are some recommended ways to update the widget based on user interaction:\n\n- **From an activity of the app:** directly call\n `AppWidgetManager.updateAppWidget` in response to a user interaction, such\n as a user's tap.\n\n- **From remote interactions, such as a notification or an app widget:**\n construct a `PendingIntent`, then update the widget from the invoked\n `Activity`, `Broadcast`, or `Service`. You can choose your own priority. For\n example, if you select a `Broadcast` for the `PendingIntent`, you can choose\n a [foreground broadcast](#broadcastreceiver-priority) to give the\n `BroadcastReceiver` priority.\n\nUpdate in response to a broadcast event\n\nAn example of a broadcast event that requires a widget to update is when the\nuser takes a photo. In this case, you want to update the widget when a new photo\nis detected.\n\nYou can schedule a job with `JobScheduler` and specify a broadcast as the\ntrigger using the\n[`JobInfo.Builder.addTriggerContentUri`](/reference/android/app/job/JobInfo.Builder#addTriggerContentUri(android.app.job.JobInfo.TriggerContentUri))\nmethod.\n\nYou can also register a `BroadcastReceiver` for the broadcast---for example,\nlistening for\n[`ACTION_LOCALE_CHANGED`](/reference/android/content/Intent#ACTION_LOCALE_CHANGED).\nHowever, because this consumes device resources, use this with care and listen\nonly to the specific broadcast. With the introduction of [broadcast\nlimitations](/about/versions/oreo/background#broadcasts) in Android\n7.0 (API level 24) and Android 8.0 (API level 26), apps can't register implicit\nbroadcasts in their manifests, with certain\n[exceptions](/guide/components/broadcast-exceptions).\n\nConsiderations when updating a widget from a BroadcastReceiver\n\nIf the widget is updated from a `BroadcastReceiver`, including\n`AppWidgetProvider`, be aware of the following considerations regarding the\nduration and priority of a widget update.\n\nDuration of the update\n\nAs a rule, the system lets broadcast receivers, which usually run in the app's\nmain thread, run for up to 10 seconds before considering them non-responsive and\ntriggering an [Application Not\nResponding](/topic/performance/vitals/anr) (ANR) error. To avoid blocking the\nmain thread while handling the broadcast, use the\n[`goAsync`](/reference/android/content/BroadcastReceiver#goAsync()) method. If it takes\nlonger to update the widget, consider scheduling a task\nusing [`WorkManager`](/reference/androidx/work/WorkManager). \n\n Caution: Any work you do here blocks further broadcasts until it completes,\n so it can slow the receiving of later events.\n\nSee [Security considerations and best\npractices](/guide/components/broadcasts#security-and-best-practices) for more\ninformation.\n\nPriority of the update\n\nBy default, broadcasts---including those made using\n`AppWidgetProvider.onUpdate`---run as background processes. This means\noverloaded system resources can cause a delay in the invocation of the broadcast\nreceiver. To prioritize the broadcast, make it a foreground process.\n\nFor example, add the\n[`Intent.FLAG_RECEIVER_FOREGROUND`](/reference/android/content/Intent#FLAG_RECEIVER_FOREGROUND)\nflag to the `Intent` passed to the `PendingIntent.getBroadcast` when the user\ntaps on a certain part of the widget."]]