Na tej stronie znajdziesz zalecane metody tworzenia bardziej zaawansowanych widżetów, które zapewniają lepsze wrażenia użytkownikom.
Optymalizacja aktualizowania treści widżetu
Aktualizowanie treści widżetu może być kosztowne obliczeniowo. Aby oszczędzać baterię, zoptymalizuj typ, częstotliwość i czas aktualizacji.
Typy aktualizacji widżetu
Widżet można aktualizować na 3 sposoby: pełna aktualizacja, częściowa aktualizacja oraz, w przypadku widżetu kolekcji, odświeżanie danych. Każda z nich ma inne koszty obliczeniowe i konsekwencje.
Poniżej znajdziesz opis każdego typu aktualizacji oraz fragmenty kodu.
Pełna aktualizacja: wywołaj
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)aby w pełni zaktualizować widżet. Spowoduje to zastąpienie wcześniej podanychRemoteViewsnowymiRemoteViews. Jest to najbardziej kosztowna obliczeniowo aktualizacja.Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also { setTextViewText(R.id.textview_widget_layout1, "Updated text1") setTextViewText(R.id.textview_widget_layout2, "Updated text2") } appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); remoteViews.setTextViewText(R.id.textview_widget_layout1, "Updated text1"); remoteViews.setTextViewText(R.id.textview_widget_layout2, "Updated text2"); appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
Częściowa aktualizacja: wywołaj
AppWidgetManager.partiallyUpdateAppWidgetaby zaktualizować części widżetu. Spowoduje to scalenie nowychRemoteViewsz wcześniej podanymiRemoteViews. Ta metoda jest ignorowana, jeśli widżet nie otrzyma co najmniej 1 pełnej aktualizacji za pomocąupdateAppWidget(int[], RemoteViews).Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also { setTextViewText(R.id.textview_widget_layout, "Updated text") } appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); remoteViews.setTextViewText(R.id.textview_widget_layout, "Updated text"); appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews);
Odświeżanie danych kolekcji: wywołaj
AppWidgetManager.notifyAppWidgetViewDataChangedaby unieważnić dane widoku kolekcji w widżecie. Spowoduje to wywołanieRemoteViewsFactory.onDataSetChanged. W międzyczasie w widżecie wyświetlane są stare dane. Za pomocą tej metody możesz bezpiecznie wykonywać kosztowne zadania synchronicznie.Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview);
Te metody możesz wywoływać z dowolnego miejsca w aplikacji, o ile ma ona ten sam identyfikator UID co odpowiednia
AppWidgetProvider klasa.
Określanie częstotliwości aktualizowania widżetu
Widżety są aktualizowane okresowo w zależności od wartości podanej w
updatePeriodMillis
atrybucie. Widżet może się aktualizować w odpowiedzi na interakcję użytkownika, aktualizacje transmisji lub obie te rzeczy.
Okresowe aktualizowanie
Częstotliwość okresowej aktualizacji możesz kontrolować, określając wartość AppWidgetProviderInfo.updatePeriodMillis w pliku XML appwidget-provider. Każda aktualizacja wywołuje metodę AppWidgetProvider.onUpdate(), w której możesz umieścić kod aktualizujący widżet. Jeśli jednak widżet musi wczytywać dane asynchronicznie lub aktualizacja trwa dłużej niż 10 sekund, rozważ alternatywne metody aktualizacji odbiornika transmisji opisane w następnej sekcji. Po 10 sekundach system uznaje BroadcastReceiver za nieodpowiadający.
updatePeriodMillis nie obsługuje wartości mniejszych niż 30 minut. Jeśli jednak chcesz wyłączyć okresowe aktualizacje, możesz określić wartość 0.
Możesz pozwolić użytkownikom na dostosowanie częstotliwości aktualizacji w konfiguracji. Mogą na przykład chcieć, aby notowania giełdowe były aktualizowane co 15 minut lub tylko 4 razy dziennie. W takim przypadku ustaw updatePeriodMillis na 0 i użyj
WorkManager zamiast.
Aktualizowanie w odpowiedzi na interakcję użytkownika
Oto kilka zalecanych sposobów aktualizowania widżetu na podstawie interakcji użytkownika:
Z poziomu aktywności aplikacji: wywołaj bezpośrednio
AppWidgetManager.updateAppWidgetw odpowiedzi na interakcję użytkownika, np. kliknięcie.Z poziomu interakcji zdalnych, np. powiadomienia lub widżetu aplikacji: utwórz
PendingIntent, a następnie zaktualizuj widżet z wywołanejActivity,BroadcastlubService. Możesz wybrać własny priorytet. Jeśli na przykład wybierzeszBroadcastdlaPendingIntent, możesz wybrać transmisję na pierwszym planie, aby nadać prioryściBroadcastReceiver.
Aktualizowanie w odpowiedzi na zdarzenie transmisji
Przykładem zdarzenia transmisji, które wymaga aktualizacji widżetu, jest zrobienie zdjęcia przez użytkownika. W takim przypadku chcesz zaktualizować widżet, gdy zostanie wykryte nowe zdjęcie.
Możesz zaplanować zadanie za pomocą JobScheduler i określić transmisję jako
wyzwalacz za pomocą
JobInfo.Builder.addTriggerContentUri
metody.
Możesz też zarejestrować BroadcastReceiver dla transmisji, np.
nasłuchiwać
ACTION_LOCALE_CHANGED.
Ponieważ jednak zużywa to zasoby urządzenia, używaj tej metody ostrożnie i nasłuchuj tylko określonej transmisji. Wraz z wprowadzeniem ograniczeń
transmisji w Androidzie
7.0 (poziom interfejsu API 24) i Androidzie 8.0 (poziom interfejsu API 26) aplikacje nie mogą rejestrować w swoich plikach manifestu transmisji niejawnych, z pewnymi
wyjątkami.
Na co zwrócić uwagę podczas aktualizowania widżetu z poziomu BroadcastReceiver
Jeśli widżet jest aktualizowany z poziomu BroadcastReceiver, w tym AppWidgetProvider, pamiętaj o tych kwestiach dotyczących czasu trwania i priorytetu aktualizacji widżetu.
Czas trwania aktualizacji
Z reguły system pozwala odbiornikom transmisji, które zwykle działają w głównym wątku aplikacji, działać przez maksymalnie 10 sekund, zanim uzna je za nieodpowiadające i wywoła błąd „Aplikacja nie odpowiada” (ANR). Aby uniknąć blokowania
głównego wątku podczas obsługi transmisji, użyj metody
goAsync. Jeśli aktualizacja widżetu trwa
dłużej, rozważ zaplanowanie zadania
za pomocą WorkManager.
Caution: Any work you do here blocks further broadcasts until it completes,
so it can slow the receiving of later events.
Więcej informacji znajdziesz w artykule Sprawy związane z bezpieczeństwem i sprawdzone metody.
Priorytet aktualizacji
Domyślnie transmisje, w tym te wykonywane za pomocą AppWidgetProvider.onUpdate, działają jako procesy w tle. Oznacza to, że przeciążone zasoby systemowe mogą spowodować opóźnienie w wywołaniu odbiornika transmisji. Aby nadać priorytet transmisji, ustaw ją jako proces na pierwszym planie.
Na przykład dodaj flagę
Intent.FLAG_RECEIVER_FOREGROUND
do Intent przekazywanego do PendingIntent.getBroadcast, gdy użytkownik
kliknie określoną część widżetu.