ניהול ועדכון של GlanceAppWidget

בקטעים הבאים מוסבר איך לעדכן את GlanceAppWidget ולנהל אותו state.

ניהול המצב של GlanceAppWidget

המחלקה שסופקה, GlanceAppWidget, נוצרת בכל פעם שהווידג'ט נוצר או נדרש עדכון, ולכן עליו להיות ללא מצב ופסיבי.

אפשר לחלק את המושג מדינה (State):

  • מצב האפליקציה: המצב או התוכן של האפליקציה שנדרשים על ידי לווידג'ט הזה. לדוגמה, רשימה של יעדים שמורים (כלומר מסד נתונים) שמוגדרים על ידי למשתמש.
  • מצב 'בקצרה': המצב הספציפי שרלוונטי רק לווידג'ט של האפליקציה ולא בהכרח ישנו או ישפיעו על מצב האפליקציה. לדוגמה, נבחרה תיבת סימון בווידג'ט, או שהוגדל מונה.

שימוש במצב האפליקציה

ווידג'טים של אפליקציות צריכים להיות פסיביים. כל אפליקציה אחראית לניהול ושכבת הנתונים שמטפלת במצבים כמו חוסר פעילות, טעינה והשתקפות של שגיאות. בממשק המשתמש של הווידג'ט.

לדוגמה, הקוד הבא מאחזר את היעדים מהזיכרון בשכבת המאגר, מספקת את רשימת היעדים השמורה מציג ממשק משתמש שונה בהתאם למצב שלו:

class DestinationAppWidget : GlanceAppWidget() {

    // ...

    @Composable
    fun MyContent() {
        val repository = remember { DestinationsRepository.getInstance() }
        // Retrieve the cache data everytime the content is refreshed
        val destinations by repository.destinations.collectAsState(State.Loading)

        when (destinations) {
            is State.Loading -> {
                // show loading content
            }

            is State.Error -> {
                // show widget error content
            }

            is State.Completed -> {
                // show the list of destinations
            }
        }
    }
}

בכל פעם שהמצב או הנתונים משתנים, האפליקציה אחראית להודיע על כך ומעדכנים את הווידג'ט. מידע נוסף זמין במאמר עדכון GlanceAppWidget.

עדכון של GlanceAppWidget

כמו שמוסבר בקטע ניהול המצב של GlanceAppWidget, ווידג'טים מתארחים בתהליך שונה. התכונה 'בקצרה' מתרגמת את התוכן RemoteViews בפועל ושולח אותם למארח. כדי לעדכן את התוכן, לוחצים על 'בקצרה' צריך ליצור מחדש את הקובץ RemoteViews ולשלוח אותו שוב.

כדי לשלוח את העדכון, צריך להפעיל את ה-method update של המופע של GlanceAppWidget, מספקים את context ואת glanceId:

MyAppWidget().update(context, glanceId)

כדי לקבל את ה-glanceId, צריך להריץ שאילתה על GlanceAppWidgetManager:

val manager = GlanceAppWidgetManager(context)
val widget = GlanceSizeModeWidget()
val glanceIds = manager.getGlanceIds(widget.javaClass)
glanceIds.forEach { glanceId ->
    widget.update(context, glanceId)
}

לחלופין, אפשר להשתמש באחד מהתוספים GlanceAppWidget update:

// Updates all placed instances of MyAppWidget
MyAppWidget().updateAll(context)

// Iterate over all placed instances of MyAppWidget and update if the state of
// the instance matches the given predicate
MyAppWidget().updateIf<State>(context) { state ->
    state == State.Completed
}

ניתן לקרוא לשיטות האלה מכל חלק באפליקציה. כי הם פונקציות של suspend, מומלץ להפעיל אותן מחוץ ל-thread הראשי היקף. בדוגמה הבאה, הם מופעלים ב-CoroutineWorker:

class DataSyncWorker(
    val context: Context,
    val params: WorkerParameters,
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        // Fetch data or do some work and then update all instance of your widget
        MyAppWidget().updateAll(context)
        return Result.success()
    }
}

למידע נוסף על קורוטינים ב-Android, ראו קורוטין (Kotlin) ב-Android.