[[["容易理解","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 (世界標準時間)。"],[],[],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."]]