בדף הזה מוסברות שיטות מומלצות ליצירת ווידג'ט מתקדם יותר כדי לשפר את חוויית המשתמש.
אופטימיזציות לעדכון תוכן הווידג'ט
עדכון תוכן הווידג'ט יכול להיות יקר מבחינת משאבי מחשוב. כדי לחסוך בצריכת הסוללה, כדאי לבצע אופטימיזציה של סוג העדכון, התדירות והתזמון.
סוגי עדכונים לווידג'טים
יש שלוש דרכים לעדכן ווידג'ט: עדכון מלא, עדכון חלקי ורענון נתונים (במקרה של ווידג'ט אוסף). לכל אחד מהם יש עלויות חישוב והשלכות שונות.
בהמשך מפורט כל סוג עדכון, ומוצגים קטעי קוד לכל סוג.
- עדכון מלא: מתקשרים אל
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)כדי לעדכן את הווידג'ט באופן מלא. הפעולה הזו תחליף אתRemoteViewsשסופק קודם ב-RemoteViewsחדש. זהו העדכון הכי יקר מבחינת חישובים.
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)
- עדכון חלקי: קוראים ל-
AppWidgetManager.partiallyUpdateAppWidgetכדי לעדכן חלקים בווידג'ט. הפעולה הזו תמזג אתRemoteViewsהחדש עםRemoteViewsשסופק קודם. השיטה הזו מתעלמת אם הווידג'ט לא מקבל לפחות עדכון מלא אחד דרךupdateAppWidget(int[], RemoteViews).
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)
- רענון נתוני האוסף: קוראים ל-call
AppWidgetManager.notifyAppWidgetViewDataChangedכדי לבטל את תוקף הנתונים של תצוגת אוסף בווידג'ט. הפעולה הזו מפעילה אתRemoteViewsFactory.onDataSetChanged. בינתיים, הנתונים הישנים מוצגים בווידג'ט. באמצעות השיטה הזו אפשר לבצע משימות יקרות באופן סינכרוני בצורה בטוחה.
val appWidgetManager = AppWidgetManager.getInstance(context) appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
אפשר להפעיל את השיטות האלה מכל מקום באפליקציה, כל עוד לאפליקציה יש את אותו UID כמו למחלקה התואמת AppWidgetProvider.
קביעת התדירות של עדכון הווידג'ט
הווידג'טים מתעדכנים מעת לעת בהתאם לערך שצוין במאפיין
updatePeriodMillis. הווידג'ט יכול להתעדכן בתגובה לאינטראקציה של המשתמש, לשדר עדכונים או לבצע את שתי הפעולות.
עדכון תקופתי
כדי לשלוט בתדירות העדכון התקופתי, מציינים ערך לפרמטר AppWidgetProviderInfo.updatePeriodMillis בקובץ ה-XML של appwidget-provider. כל עדכון מפעיל את השיטה AppWidgetProvider.onUpdate(), שבה אפשר להציב את הקוד לעדכון הווידג'ט. עם זאת, אם הווידג'ט צריך לטעון נתונים באופן אסינכרוני או שלוקח לו יותר מ-10 שניות להתעדכן, כדאי לשקול את החלופות לעדכונים של מקלטי שידור שמתוארות בקטע הבא, כי אחרי 10 שניות המערכת מחשיבה את BroadcastReceiver כלא מגיב.
המאפיין updatePeriodMillis לא תומך בערכים של פחות מ-30 דקות. עם זאת, אם רוצים להשבית את העדכונים התקופתיים, אפשר לציין 0.
אתם יכולים לאפשר למשתמשים לשנות את תדירות העדכונים בהגדרה. לדוגמה, הם יכולים לרצות שהעדכון של נתוני מניות יתבצע כל 15 דקות או רק ארבע פעמים ביום. במקרה כזה, צריך להגדיר את updatePeriodMillis ל-0 ולהשתמש ב-WorkManager.
עדכון בתגובה לאינטראקציה של משתמש
ריכזנו כאן כמה דרכים מומלצות לעדכן את הווידג'ט על סמך אינטראקציה של המשתמשים:
מפעילות של האפליקציה: קריאה ישירה ל-
AppWidgetManager.updateAppWidgetבתגובה לאינטראקציה של משתמש, כמו הקשה של משתמש.מאינטראקציות מרחוק, כמו התראה או ווידג'ט של אפליקציה: יוצרים
PendingIntent, ואז מעדכנים את הווידג'ט מה-Activity,BroadcastאוServiceשהופעלו. אתם יכולים לבחור את העדיפות שלכם. לדוגמה, אם בוחריםBroadcastבשבילPendingIntent, אפשר לבחור שידור בחזית כדי לתת עדיפות לBroadcastReceiver.
עדכון בתגובה לאירוע שידור
דוגמה לאירוע שידור שדורש עדכון של הווידג'ט היא כשמשתמש מצלם תמונה. במקרה הזה, רוצים לעדכן את הווידג'ט כשמזוהה תמונה חדשה.
אפשר לתזמן עבודה עם WorkManager ולציין טריגר של URI של תוכן באמצעות השיטה Constraints.Builder.addContentUriTrigger.
אפשר גם להירשם לBroadcastReceiverשידור – לדוגמה, להאזין לACTION_LOCALE_CHANGED.
עם זאת, מכיוון שהפעולה הזו צורכת משאבי מכשיר, חשוב להשתמש בה בזהירות ולהאזין רק לשידור הספציפי. עם השקת מגבלות על שידורים ב-Android 7.0 (רמת API 24) וב-Android 8.0 (רמת API 26), אפליקציות לא יכולות לרשום שידורים מרומזים במניפסטים שלהן, עם חריגים מסוימים.
שיקולים כשמעדכנים ווידג'ט מ-BroadcastReceiver
אם הווידג'ט מתעדכן מ-BroadcastReceiver, כולל AppWidgetProvider, חשוב לשים לב לשיקולים הבאים לגבי משך הזמן והעדיפות של עדכון הווידג'ט.
משך העדכון
ככלל, המערכת מאפשרת ל-broadcast receivers, שפועלים בדרך כלל ב-main thread של האפליקציה, לפעול עד 10 שניות לפני שהיא מחשיבה אותם כלא מגיבים ומפעילה שגיאת Application Not Responding (ANR). כדי להימנע מחסימת השרשור הראשי בזמן הטיפול בשידור, משתמשים בשיטה goAsync. אם העדכון של הווידג'ט נמשך זמן רב, כדאי לתזמן משימה באמצעות WorkManager.
Caution: Any work you do here blocks further broadcasts until it completes,
so it can slow the receiving of later events.
מידע נוסף זמין במאמר בנושא שיקולי אבטחה ושיטות מומלצות.
העדיפות של העדכון
כברירת מחדל, שידורים – כולל שידורים שמתבצעים באמצעות AppWidgetProvider.onUpdate – פועלים כתהליכי רקע. המשמעות היא שמשאבי מערכת עמוסים מדי עלולים לגרום לעיכוב בהפעלת מקלט השידור. כדי לתת עדיפות לשידור, צריך להגדיר אותו כתהליך בחזית.
לדוגמה, אפשר להוסיף את הדגל Intent.FLAG_RECEIVER_FOREGROUND
ל-Intent שמועבר אל PendingIntent.getBroadcast כשמשתמש מקיש על חלק מסוים בווידג'ט.