בדף הזה מוסברות שיטות מומלצות ליצירת ווידג'ט מתקדם יותר, כדי לשפר את חוויית המשתמש.
אופטימיזציות לעדכון תוכן הווידג'ט
עדכון תוכן של ווידג'ט יכול להיות יקר מבחינת משאבי המחשוב. כדי לחסוך בצריכת הסוללה, כדאי לבצע אופטימיזציה של סוג העדכון, התדירות והתזמון.
סוגי העדכונים של הווידג'ט
יש שלוש דרכים לעדכן ווידג'ט: עדכון מלא, עדכון חלקי, ובמקרה של ווידג'ט של אוסף, רענון נתונים. לכל אחת מהן יש עלויות והשלכות חישוביות שונות.
בהמשך מתואר כל סוג עדכון ומוצגים קטעי קוד לכל אחד מהם.
- עדכון מלא: קוראים ל-
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)
- רענון נתוני האוסף: קוראים לפונקציה
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, חשוב לשים לב לשיקולים הבאים לגבי משך הזמן והעדיפות של עדכון הווידג'ט.
משך העדכון
ככלל, המערכת מאפשרת למקלטי שידור, שבדרך כלל פועלים בשרשור הראשי של האפליקציה, לפעול עד 10 שניות לפני שהיא מחשיבה אותם כלא מגיבים ומפעילה שגיאת האפליקציה לא מגיבה (ANR). כדי להימנע מחסימת ה-thread הראשי בזמן הטיפול בשידור, משתמשים ב-method 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 כשהמשתמש מקיש על חלק מסוים בווידג'ט.