Bu sayfada, kullanıcı deneyimini iyileştirmeye yardımcı olur.
Widget içeriğini güncellemek için optimizasyonlar
Widget içeriğini güncellemek işlem yükü açısından pahalı olabilir. Pilden tasarruf etmek için tüketimi, güncelleme türünü, sıklığını ve zamanlamayı optimize edin.
Widget güncellemesi türleri
Bir widget'ı güncellemenin üç yolu vardır: tam güncelleme, kısmi güncelleme ve koleksiyonu widget'ında veri yenileme işlemi yapılır. Her biri farklı ve sonuçları.
Aşağıda, her güncelleme türü açıklanmakta ve her biri için kod snippet'leri sunulmaktadır.
Güncellemenin tamamı:
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)
numaralı telefonu arayın widget'ı tamamen güncelleyin. Bu, daha önce sağlananRemoteViews
- yeni birRemoteViews
. Bu, işlem açısından en pahalı güncellemedir.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);
Kısmi güncelleme: arama
AppWidgetManager.partiallyUpdateAppWidget
widget'ın belirli bölümlerini güncelleyin. Bu işlem, yeniRemoteViews
öğesini önceden sağlananRemoteViews
. Bir widgetupdateAppWidget(int[], RemoteViews)
üzerinden en az bir tam güncelleme almaz.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);
Koleksiyon verilerini yenileme: çağrı
AppWidgetManager.notifyAppWidgetViewDataChanged
kullanarak widget'ınızdaki bir koleksiyon görünümünün verilerini geçersiz kılabilirsiniz. Bu, tetikleyiciRemoteViewsFactory.onDataSetChanged
. Bu sırada widget'ta eski veriler gösterilir. Güvenle pahalı görevleri bu yöntemle eşzamanlı olarak gerçekleştirebilirsiniz.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);
Uygulamanızın herhangi bir yerindeyken bu yöntemleri çağırabilirsiniz. Önemli olan
karşılık gelen ile aynı UID
AppWidgetProvider
sınıfı.
Bir widget'ın ne sıklıkta güncelleneceğini belirleme
Widget'lar,
updatePeriodMillis
özelliğini gönderin. Widget, kullanıcı etkileşimine bağlı olarak güncellenebilir.
veya her ikisini birden yapabilirsiniz.
Düzenli aralıklarla güncelleme
Periyodik güncellemenin sıklığını kontrol etmek için
appwidget-provider
XML'de AppWidgetProviderInfo.updatePeriodMillis
. Her biri
güncelleme, AppWidgetProvider.onUpdate()
yöntemini tetikler. Bu yöntemde
widget'ı güncellemek için kod yerleştirebilir. Ancak, projenizin alternatifleri olan
yayın alıcı güncellemelerinin
widget'ınızın verileri eşzamansız olarak yüklemesi gerekiyorsa veya daha fazla zaman alıyorsa
10 saniyeden fazladır. Çünkü 10 saniyeden sonra, sistem bir
BroadcastReceiver
yanıt vermeyecek.
updatePeriodMillis
, 30 dakikadan kısa değerleri desteklemiyor. Ancak,
periyodik güncellemeleri devre dışı bırakmak istiyorsanız 0 değerini belirtebilirsiniz.
Kullanıcıların bir yapılandırmada güncellemelerin sıklığını ayarlamasına izin verebilirsiniz. Örneğin,
bir borsa takip cihazının her 15 dakikada bir
veya yalnızca dört dakikada bir güncellenmesini
günde birkaç kez. Bu durumda, updatePeriodMillis
değerini 0 olarak ayarlayın ve
Bunun yerine WorkManager
.
Kullanıcı etkileşimine yanıt olarak güncelleme
Widget'ı kullanıcı etkileşimine göre güncellemek için önerilen yöntemlerden bazıları şunlardır:
Uygulamanın bir etkinliğinden: Doğrudan arama
AppWidgetManager.updateAppWidget
, şu gibi bir kullanıcı etkileşimine yanıt olarak: kullanıcının dokunuşu olarak değişir.Bildirim veya uygulama widget'ı gibi uzaktan etkileşimlerden: bir
PendingIntent
oluşturun, ardından çağrılanActivity
,Broadcast
veyaService
. Kendi önceliğinizi seçebilirsiniz. Örneğin, Örneğin,PendingIntent
için birBroadcast
seçerseniz bir ön plan yayını yapabilirsiniz.BroadcastReceiver
öncelik.
Yayın etkinliğine yanıt olarak güncelleme
Widget'ın güncellenmesi gereken bir yayın etkinliğine örnek olarak, bir fotoğraf çektiğini varsayalım. Bu durumda, yeni bir fotoğraf eklendiğinde widget'ı tespit edilir.
JobScheduler
ile bir iş planlayabilir ve
tetikleyicinin
JobInfo.Builder.addTriggerContentUri
yöntemidir.
Ayrıca yayın için bir BroadcastReceiver
kaydettirebilirsiniz. Örneğin,
dinleniyor
ACTION_LOCALE_CHANGED
Ancak bu işlem cihaz kaynaklarını tükettiği için bunu yaparken dikkatli olun ve dinleyin
belirli bir yayın ile ilişkilendirilir. Yayınların kullanıma sunulmasıyla birlikte
sınırlamaları
7.0 (API düzeyi 24) ve Android 8.0 (API düzeyi 26) sürümleriyle uygulamalar örtülü kaydedemez
bunların belirli bir kısmı,
istisnalar.
BroadcastRecipientr'dan widget güncellerken dikkat edilmesi gereken noktalar
Widget, aşağıdakiler dahil bir BroadcastReceiver
üzerinden güncellenirse:
AppWidgetProvider
,
güncellemenin süresini ve önceliğini kontrol edin.
Güncelleme süresi
Kural olarak, sistem genellikle uygulamanın içinde çalışan yayın alıcılarına izin verir. ana iş parçacığının, duyarlı olmadığını ve yanıt vermediğini kabul etmeden önce 10 saniyeye kadar çalıştırın bir Uygulama Notunu Yanıt Verme (ANR) hatası. Daha uzun sürerse widget'ı güncelledikten sonra aşağıdaki alternatifleri göz önünde bulundurun:
WorkManager
kullanarak görev planlayın.Alıcıya
goAsync
yöntemini kullanabilirsiniz. Bu, alıcıların 30 saniye boyunca yürütmesini sağlar.
Güvenlikle ilgili olarak göz önünde bulundurulması gerekenler ve en iyi daha fazla bilgi için ekleyebilirsiniz.
Güncellemenin önceliği
Varsayılan olarak,
AppWidgetProvider.onUpdate
: Arka plan işlemleri olarak çalışır. Bunun anlamı şudur:
sistem kaynaklarının aşırı yüklenmesi, yayının çağrılmasında gecikmeye neden olabilir
alıcı. Yayına öncelik vermek için yayını ön plan işlemi yapın.
Örneğin,
Intent.FLAG_RECEIVER_FOREGROUND
kullanıcı tarafından gerçekleştirildiğinde PendingIntent.getBroadcast
öğesine iletilen Intent
öğesine işaret
widget'ın belirli bir bölümüne
dokunduğunda,
Dinamik öğeler içeren doğru önizlemeler oluşturun
![](https://developer.android.com/static/images/appwidgets/missing-list.png?hl=tr)
Bu bölümde, aynı görünümde birden fazla öğe görüntülemek için önerilen yaklaşım
koleksiyonu olan bir widget'ın widget önizlemesi
görünüm: yani bir widget kullanan bir widget
ListView
, GridView
veya StackView
.
Widget'ınız bu görünümlerden birini kullanıyorsa doğrudan widget'ın kendisini sunmak düzen, önizlemede hiçbir öğe görüntülenmediğinde yeni bir deneyim yaşayabilirsiniz. Bunun nedeni, koleksiyon görünümü verileri çalışma zamanında dinamik olarak ayarlanır ve bu veriler ilgili resim gösterilmektedir.
Widget'ların koleksiyon görünümlerine sahip önizlemelerinin widget'ta düzgün bir şekilde görüntülenmesini sağlamak için
yalnızca
önizle. Bu ayrı düzen dosyası, gerçek widget düzenini ve bir
sahte öğeler içeren yer tutucu koleksiyon görünümü Örneğin, bir
Çok sayıda sahte liste içeren LinearLayout
yer tutucusu sağlayarak ListView
öğeler.
ListView
örneğini göstermek için ayrı bir düzen dosyasıyla başlayın:
// res/layout/widget_preview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/widget_background"
android:orientation="vertical">
// Include the actual widget layout that contains ListView.
<include
layout="@layout/widget_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
// The number of fake items you include depends on the values you provide
// for minHeight or targetCellHeight in the AppWidgetProviderInfo
// definition.
<TextView android:text="@string/fake_item1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
<TextView android:text="@string/fake_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
</LinearLayout>
Şu öğenin previewLayout
özelliğini sağlarken önizleme düzeni dosyasını belirtin:
AppWidgetProviderInfo
meta verileri. Yine de gerçek widget düzenini belirtirsiniz
ve aşağıdaki durumlarda gerçek widget düzenini kullanın:initialLayout
çalışma zamanında bir RemoteViews
oluşturuyoruz.
<appwidget-provider
previewLayout="@layout/widget_previe"
initialLayout="@layout/widget_view" />
Karmaşık liste öğeleri
Önceki bölümdeki örnek sahte liste öğeleri sağlıyor çünkü
öğe TextView
nesne. Bu,
öğeler karmaşık düzenlerse sahte öğelerin sağlanması daha karmaşıktır.
widget_list_item.xml
içinde tanımlanmış ve şunlardan oluşan bir liste öğesini düşünün
iki TextView
nesnesi var:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_title" />
<TextView android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_content" />
</LinearLayout>
Sahte liste öğeleri sağlamak için düzeni birden fazla kez ekleyebilirsiniz, ancak her liste öğesinin aynı olmasına neden olur. Benzersiz liste öğeleri sağlamak için şu adımları uygulayın:
Metin değerleri için bir özellik grubu oluşturun:
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>
Metni ayarlamak için şu özellikleri kullanın:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetTitle" /> <TextView android:id="@id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetContent" /> </LinearLayout>
Önizleme için gereken sayıda stil oluşturun. Şuradaki değerleri yeniden tanımla: her stil:
<resources> <style name="Theme.Widget.ListItem"> <item name="widgetTitle"></item> <item name="widgetContent"></item> </style> <style name="Theme.Widget.ListItem.Preview1"> <item name="widgetTitle">Fake Title 1</item> <item name="widgetContent">Fake content 1</item> </style> <style name="Theme.Widget.ListItem.Preview2"> <item name="widgetTitle">Fake title 2</item> <item name="widgetContent">Fake content 2</item> </style> </resources>
Önizleme düzenindeki sahte öğelere stil uygulayın:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" ...> <include layout="@layout/widget_view" ... /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview1" /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview2" /> </LinearLayout>