Auf dieser Seite werden empfohlene Vorgehensweisen für die Erstellung eines erweiterten Widgets beschrieben, um die Nutzerfreundlichkeit zu verbessern.
Optimierungen für die Aktualisierung von Widget-Inhalten
Das Aktualisieren von Widget-Inhalten kann rechenintensiv sein. Um den Akkuverbrauch zu senken, optimiere den Aktualisierungstyp, die Häufigkeit und das Timing.
Arten von Widget-Updates
Es gibt drei Möglichkeiten, ein Widget zu aktualisieren: eine vollständige Aktualisierung, eine teilweise Aktualisierung und, im Fall eines Sammlungs-Widgets, eine Datenaktualisierung. Jede Art hat unterschiedliche Rechenkosten und Auswirkungen.
Im Folgenden werden die einzelnen Aktualisierungstypen beschrieben und Code-Snippets für jeden Typ bereitgestellt.
- Vollständiges Update: Rufen Sie
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)auf, um das Widget vollständig zu aktualisieren. Dadurch wird die zuvor bereitgestellteRemoteViewsdurch eine neueRemoteViewsersetzt. Dies ist die rechenintensivste Aktualisierung.
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.packageName, R.layout.widgetlayout).apply { setTextViewText(R.id.textview_widget_layout1, "Updated text1") setTextViewText(R.id.textview_widget_layout2, "Updated text2") } appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
- Teilweises Update: Rufen Sie
AppWidgetManager.partiallyUpdateAppWidgetauf, um Teile des Widgets zu aktualisieren. Dadurch wird die neueRemoteViewsmit der zuvor bereitgestelltenRemoteViewszusammengeführt. Diese Methode wird ignoriert, wenn ein Widget nicht mindestens ein vollständiges Update überupdateAppWidget(int[], RemoteViews)erhält.
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.packageName, R.layout.widgetlayout).apply { setTextViewText(R.id.textview_widget_layout, "Updated text") } appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)
- Aktualisierung der Sammlungsdaten:Rufe
AppWidgetManager.notifyAppWidgetViewDataChangedauf, um die Daten einer Sammlungsansicht in deinem Widget ungültig zu machen. Dadurch wirdRemoteViewsFactory.onDataSetChangedausgelöst. In der Zwischenzeit werden die alten Daten im Widget angezeigt. Mit dieser Methode können Sie rechenintensive Aufgaben synchron ausführen.
val appWidgetManager = AppWidgetManager.getInstance(context) appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
Sie können diese Methoden von überall in Ihrer App aufrufen, solange die App dieselbe UID wie die entsprechende AppWidgetProvider-Klasse hat.
Festlegen, wie oft ein Widget aktualisiert werden soll
Widgets werden regelmäßig aktualisiert, je nachdem, welcher Wert für das Attribut updatePeriodMillis angegeben wurde. Das Widget kann als Reaktion auf Nutzerinteraktionen, Broadcast-Updates oder beides aktualisiert werden.
Regelmäßig aktualisieren
Sie können die Häufigkeit der regelmäßigen Aktualisierung steuern, indem Sie in der XML-Datei appwidget-provider einen Wert für AppWidgetProviderInfo.updatePeriodMillis angeben. Jedes Update löst die Methode AppWidgetProvider.onUpdate() aus. Hier können Sie den Code zum Aktualisieren des Widgets platzieren. Wenn dein Widget Daten asynchron laden muss oder die Aktualisierung länger als 10 Sekunden dauert, solltest du die im folgenden Abschnitt beschriebenen Alternativen für Aktualisierungen des Übertragungsempfängers in Betracht ziehen, da das System nach 10 Sekunden davon ausgeht, dass ein BroadcastReceiver nicht reagiert.
updatePeriodMillis unterstützt keine Werte unter 30 Minuten. Wenn Sie jedoch regelmäßige Updates deaktivieren möchten, können Sie 0 angeben.
Sie können Nutzern erlauben, die Häufigkeit von Updates in einer Konfiguration anzupassen. Beispielsweise möchten sie, dass ein Börsenticker alle 15 Minuten oder nur viermal am Tag aktualisiert wird. Setzen Sie in diesem Fall updatePeriodMillis auf 0 und verwenden Sie stattdessen WorkManager.
Aktualisierung als Reaktion auf eine Nutzerinteraktion
Hier sind einige empfohlene Möglichkeiten, das Widget basierend auf der Nutzerinteraktion zu aktualisieren:
Über eine Aktivität der App:Rufe
AppWidgetManager.updateAppWidgetdirekt als Reaktion auf eine Nutzerinteraktion auf, z. B. wenn ein Nutzer tippt.Bei Remote-Interaktionen, z. B. einer Benachrichtigung oder einem App-Widget:Erstelle ein
PendingIntent-Objekt und aktualisiere das Widget dann über den aufgerufenenActivity,BroadcastoderService. Sie können Ihre eigene Priorität festlegen. Wenn Sie beispielsweise einenBroadcastfür diePendingIntentauswählen, können Sie einen Vordergrund-Broadcast auswählen, um demBroadcastReceiverPriorität zu geben.
Aktualisierung als Reaktion auf ein Broadcast-Ereignis
Ein Beispiel für ein Broadcast-Ereignis, das eine Aktualisierung des Widgets erfordert, ist, wenn der Nutzer ein Foto aufnimmt. In diesem Fall möchten Sie das Widget aktualisieren, wenn ein neues Foto erkannt wird.
Sie können Aufgaben mit WorkManager planen und einen Inhalts-URI-Trigger mit der Methode Constraints.Builder.addContentUriTrigger angeben.
Du kannst auch einen BroadcastReceiver für die Übertragung registrieren, z. B. um auf ACTION_LOCALE_CHANGED zu warten.
Da dies jedoch Geräteressourcen verbraucht, solltest du diese Funktion mit Bedacht verwenden und nur auf die spezifische Übertragung warten. Mit der Einführung von Broadcast-Einschränkungen in Android 7.0 (API-Level 24) und Android 8.0 (API-Level 26) können Apps keine impliziten Broadcasts in ihren Manifesten registrieren, mit bestimmten Ausnahmen.
Hinweise zum Aktualisieren eines Widgets über einen BroadcastReceiver
Wenn das Widget über ein BroadcastReceiver aktualisiert wird, einschließlich AppWidgetProvider, beachten Sie die folgenden Hinweise zur Dauer und Priorität einer Widget-Aktualisierung.
Dauer des Updates
In der Regel lässt das System Übertragungsempfänger, die normalerweise im Hauptthread der App ausgeführt werden, bis zu 10 Sekunden lang laufen, bevor es sie als nicht reagierend einstuft und einen ANR-Fehler (Application Not Responding) auslöst. Verwenden Sie die Methode goAsync, um zu vermeiden, dass der Hauptthread während der Verarbeitung des Broadcasts blockiert wird. Wenn die Aktualisierung des Widgets länger dauert, können Sie eine Aufgabe mit WorkManager planen.
Caution: Any work you do here blocks further broadcasts until it completes,
so it can slow the receiving of later events.
Weitere Informationen finden Sie unter Sicherheitsaspekte und Best Practices.
Priorität des Updates
Standardmäßig werden Broadcasts, einschließlich der mit AppWidgetProvider.onUpdate erstellten, als Hintergrundprozesse ausgeführt. Das bedeutet, dass überlastete Systemressourcen zu einer Verzögerung beim Aufruf des Übertragungsempfängers führen können. Wenn Sie die Übertragung priorisieren möchten, machen Sie sie zu einem Vordergrundprozess.
Fügen Sie beispielsweise das Flag Intent.FLAG_RECEIVER_FOREGROUND zum Intent hinzu, das an den PendingIntent.getBroadcast übergeben wird, wenn der Nutzer auf einen bestimmten Teil des Widgets tippt.