Halaman ini menjelaskan praktik yang direkomendasikan untuk membuat widget yang lebih canggih demi pengalaman pengguna yang lebih baik.
Pengoptimalan untuk memperbarui konten widget
Memperbarui konten widget dapat memerlukan banyak komputasi. Untuk menghemat konsumsi baterai, optimalkan jenis, frekuensi, dan waktu pembaruan.
Jenis pembaruan widget
Ada tiga cara untuk memperbarui widget: pembaruan penuh, pembaruan sebagian, dan, dalam kasus widget koleksi, refresh data. Setiap cara memiliki biaya komputasi dan konsekuensi yang berbeda.
Berikut ini penjelasan tentang setiap jenis pembaruan dan cuplikan kode untuk setiap jenis.
Pembaruan penuh: panggil
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)untuk memperbarui widget sepenuhnya. Tindakan ini akan mengganti yang sebelumnya diberikanRemoteViewsdengan yang baruRemoteViews. Ini adalah pembaruan yang paling mahal secara komputasi.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);
Pembaruan sebagian: panggil
AppWidgetManager.partiallyUpdateAppWidgetuntuk memperbarui bagian widget. Tindakan ini akan menggabungkanRemoteViewsbaru denganRemoteViewsyang sebelumnya diberikan. Metode ini diabaikan jika widget tidak menerima setidaknya satu pembaruan penuh melaluiupdateAppWidget(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);
Refresh data koleksi: panggil
AppWidgetManager.notifyAppWidgetViewDataChangeduntuk membatalkan data tampilan koleksi di widget Anda. Tindakan ini akan memicuRemoteViewsFactory.onDataSetChanged. Sementara itu, data lama akan ditampilkan di widget. Anda dapat melakukan tugas yang mahal secara komputasi dengan aman secara sinkron menggunakan metode ini.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);
Anda dapat memanggil metode ini dari mana saja di aplikasi, selama aplikasi memiliki
UID yang sama dengan class yang sesuai
AppWidgetProvider.
Menentukan frekuensi pembaruan widget
Widget diperbarui secara berkala, bergantung pada nilai yang diberikan untuk atribut
updatePeriodMillis. Widget dapat diperbarui sebagai respons terhadap interaksi pengguna, pembaruan siaran, atau keduanya.
Memperbarui secara berkala
Anda dapat mengontrol frekuensi pembaruan berkala dengan menentukan nilai untuk AppWidgetProviderInfo.updatePeriodMillis di XML appwidget-provider. Setiap pembaruan akan memicu metode AppWidgetProvider.onUpdate(), tempat Anda dapat menempatkan kode untuk memperbarui widget. Namun, pertimbangkan alternatif untuk
pembaruan penerima siaran yang dijelaskan di
bagian berikut jika widget Anda perlu memuat data secara asinkron atau memerlukan waktu lebih
dari 10 detik untuk diperbarui, karena setelah 10 detik, sistem akan menganggap
BroadcastReceiver tidak responsif.
updatePeriodMillis tidak mendukung nilai kurang dari 30 menit. Namun, jika ingin menonaktifkan pembaruan berkala, Anda dapat menentukan 0.
Anda dapat mengizinkan pengguna menyesuaikan frekuensi pembaruan dalam konfigurasi. Misalnya, mereka mungkin ingin simbol saham diperbarui setiap 15 menit atau hanya empat kali sehari. Dalam hal ini, tetapkan updatePeriodMillis ke 0 dan gunakan
WorkManager sebagai gantinya.
Memperbarui sebagai respons terhadap interaksi pengguna
Berikut beberapa cara yang direkomendasikan untuk memperbarui widget berdasarkan interaksi pengguna:
Dari aktivitas aplikasi: panggil
AppWidgetManager.updateAppWidgetsecara langsung sebagai respons terhadap interaksi pengguna, seperti ketukan pengguna.Dari interaksi jarak jauh, seperti notifikasi atau widget aplikasi: buat
PendingIntent, lalu perbarui widget dariActivity,Broadcast, atauServiceyang dipanggil. Anda dapat memilih prioritas sendiri. Misalnya, jika memilihBroadcastuntukPendingIntent, Anda dapat memilih siaran latar depan untuk memberikanBroadcastReceiverprioritas.
Memperbarui sebagai respons terhadap peristiwa siaran
Contoh peristiwa siaran yang mengharuskan widget diperbarui adalah saat pengguna mengambil foto. Dalam hal ini, Anda ingin memperbarui widget saat foto baru terdeteksi.
Anda dapat menjadwalkan tugas dengan JobScheduler dan menentukan siaran sebagai
pemicu menggunakan
JobInfo.Builder.addTriggerContentUri
metode.
Anda juga dapat mendaftarkan BroadcastReceiver untuk siaran—misalnya,
mendengarkan
ACTION_LOCALE_CHANGED.
Namun, karena hal ini menggunakan resource perangkat, gunakan dengan hati-hati dan hanya dengarkan siaran tertentu. Dengan diperkenalkannya siaran
batasan di Android
7.0 (API level 24) dan Android 8.0 (API level 26), aplikasi tidak dapat mendaftarkan siaran implisit dalam manifesnya, dengan
pengecualian tertentu.
Pertimbangan saat memperbarui widget dari BroadcastReceiver
Jika widget diperbarui dari BroadcastReceiver, termasuk AppWidgetProvider, perhatikan pertimbangan berikut terkait durasi dan prioritas pembaruan widget.
Durasi pembaruan
Sebagai aturan, sistem memungkinkan penerima siaran, yang biasanya berjalan di thread utama aplikasi, berjalan hingga 10 detik sebelum dianggap tidak responsif dan memicu error Aplikasi Tidak Merespons (ANR). Untuk menghindari pemblokiran the
main thread saat menangani siaran, gunakan the
goAsync method. Jika memerlukan waktu
lebih lama untuk memperbarui widget, pertimbangkan untuk menjadwalkan tugas
menggunakan WorkManager.
Caution: Any work you do here blocks further broadcasts until it completes,
so it can slow the receiving of later events.
Lihat Pertimbangan keamanan dan praktik terbaik untuk mengetahui informasi selengkapnya.
Prioritas pembaruan
Secara default, siaran—termasuk yang dibuat menggunakan AppWidgetProvider.onUpdate—berjalan sebagai proses latar belakang. Artinya, resource sistem yang kelebihan beban dapat menyebabkan penundaan dalam pemanggilan penerima siaran. Untuk memprioritaskan siaran, jadikan siaran sebagai proses latar depan.
Misalnya, tambahkan flag
Intent.FLAG_RECEIVER_FOREGROUND
ke Intent yang diteruskan ke PendingIntent.getBroadcast saat pengguna
mengetuk bagian tertentu dari widget.