עדכון עבודה שכבר נוספה לתור

ב-WorkManager אפשר לעדכן WorkRequest לאחר שכבר מתבצע צירפו אותו לתור. הדרישה הזו נחוצה בדרך כלל באפליקציות גדולות יותר שמשתנות לעיתים קרובות אילוצים או לעדכן את העובדים שלהם תוך כדי תנועה. נכון ל-WorkManager בגרסה 2.8.0, ה-API של updateWork() הוא הדרך לעשות את זה.

השיטה updateWork() מאפשרת לשנות היבטים מסוימים של WorkRequest בדרכים, בלי לבצע את התהליך של ביטול והוספה של חוק חדש לתור. זה מפשט מאוד את הפיתוח תהליך האימות.

הימנעות מביטול עבודה

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

הדוגמאות הבאות מציגות מקרים שבהם ביטול של WorkRequest עלול לגרום קשיים:

  • בקשה לקצה העורפי: אם מבטלים Worker בזמן שהוא מחשב מטען ייעודי (payload) שיישלח לשרת, ה-Worker החדש צריך להתחיל מחדש ו לחשב מחדש את המטען הייעודי (payload) שעשוי להיות יקר.
  • תזמון: אם תבטלו PeriodicWorkRequest ותרצו כמו PeriodicWorkRequest החדש להפעלה באותו לוח זמנים, צריך כדי לחשב קיזוז זמן ולוודא שזמן הביצוע החדש תואם עם בקשת העבודה הקודמת.

ה-API של updateWork() מאפשר לעדכן את האילוצים של בקשות עבודה פרמטרים אחרים ללא הטרחה של ביטול והוספה של בקשה חדשה לתור.

מתי מבטלים את העבודה

יש מקרים שבהם צריך לבטל את WorkRequest באופן ישיר ולא קוראים לפונקציה updateWork(). זה מה שצריך לעשות אם רוצים לשנות את האופי הבסיסי של היצירה שהוספת לתור.

מתי לעדכן את פרופיל העבודה

נניח שאפליקציית תמונות מאפשרת גיבוי יומי של התמונות של המשתמש. יש בו צירפו PeriodicWorkRequest כדי לעשות זאת. ב-WorkRequest יש מגבלות שבהן נדרש שהמכשיר יהיה בטעינה ומחובר ל-Wi-Fi.

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

במצב הזה, אפשר להשתמש בשיטה updateWork() כדי לעדכן את היצירה. אילוצים של הבקשה.

איך מעדכנים את כתובת העבודה

באמצעות השיטה updateWork() אפשר פשוט לעדכן חשבון קיים WorkRequest, בלי שיהיה צורך לבטל ולהוסיף הזמנה חדשה לתור.

כדי להשתמש בעדכון העבודה הממתינה, מבצעים את השלבים הבאים:

  1. קבלת המזהה הקיים של עבודה שנמצאת בתור: קבלת המזהה של בקשת ה-WorkRequest רוצה לעדכן. אפשר לאחזר את המזהה הזה עם כל אחד getWorkInfo ממשקי API, או על ידי שמירה ידנית של המזהה בקשת עבודה לאחזור במועד מאוחר יותר באמצעות הנכס הציבורי WorkRequest.id, לפני הוספת הפריט לתור.
  2. יצירת WorkRequest חדש: יוצרים WorkRequest חדש ומשתמשים בו WorkRequest.Builder.setID() כדי להגדיר את המזהה שלו כך שיהיה זהה לזה של המזהה הקיים WorkRequest.
  3. הגדרת מגבלות: משתמשים ב-WorkRequest.Builder.setConstraints() כדי להעביר את אילוצים חדשים של WorkManager.
  4. Call updateWork: מעבירים את בקשת WorkRequest החדשה אל updateWork().

עדכון דוגמה לעבודה

הנה קטע קוד לדוגמה ב-Kotlin שמדגים איך להשתמש שיטה updateWork() לשינוי מגבלות הסוללה של WorkRequest בשימוש כדי להעלות תמונות:

suspend fun updatePhotoUploadWork() {
    // Get instance of WorkManager.
    val workManager = WorkManager.getInstance(context)

    // Retrieve the work request ID. In this example, the work being updated is unique
    // work so we can retrieve the ID using the unique work name.
    val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
        PHOTO_UPLOAD_WORK_NAME
    ).await()

    val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return

    // Update the constraints of the WorkRequest to not require a charging device.
    val newConstraints = Constraints.Builder()
        // Add other constraints as required here.
        .setRequiresCharging(false)
        .build()

    // Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
    val updatedWorkRequest: WorkRequest =
        OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(newConstraints)
            .setId(existingWorkRequestId)
            .build()

    // Pass the new WorkRequest to updateWork().
    workManager.updateWork(updatedWorkRequest)
}

טיפול בתוצאה

הפונקציה updateWork() מחזירה ListenableFuture<UpdateResult>. הנתון ל-UpdateResult יכול להיות אחד מהערכים, שמתאר אם מערכת WorkManager הצליחה להחיל את השינויים שלך. מצוין גם מתי היא הצליחה כדי להחיל את השינוי.

מידע נוסף זמין בupdateWork() וגם UpdateResult חומר עזר.

מעקב אחר עבודה עם דורות

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

כדי ליצור WorkRequest, צריך לפעול לפי השלבים הבאים:

  1. WorkInfo: מבצעים קריאה אל WorkManager.getWorkInfoById() כדי לאחזר מכונה מתוך WorkInfo שתואמים ל-WorkRequest שלך.
  2. getGeneration: קוראים לפונקציה getGeneration() במופע של WorkInfo. הערך של Int שהוחזר תואם ליצירת WorkRequest.
    • שים לב שאין שדה גנרציה או נכס, אלא רק אמצעי תשלום אחד (WorkInfo.getGeneration()).

דוגמה ליצירת מסלול

הדוגמה הבאה היא הטמעה של תהליך העבודה שתואר למעלה עבור אחזור הגנרציה של WorkRequest.

// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)

// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)

// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()

מדיניות לעדכון עבודות

בעבר, הפתרון המומלץ לעדכון עבודות תקופתיות היה שליחת הזמנה לתור PeriodicWorkRequest עם המדיניות ExistingPeriodicWorkPolicy.REPLACE. אם קיים PeriodicWorkRequest בהמתנה עם אותו id ייחודי, הערך החדש בקשת העבודה תבוטל ותמחק אותה. המדיניות הזו הוצאה משימוש עכשיו ב- לטובת תהליך העבודה באמצעות ExistingPeriodicWorkPolicy.UPDATE.

לדוגמה, כשמשתמשים ב-enqueueUniquePeriodicWork עם PeriodicWorkRequest, אפשר לאתחל את PeriodicWorkRequest החדש באמצעות המדיניות בנושא ExistingPeriodicWorkPolicy.UPDATE. אם יש בקשה בהמתנה PeriodicWorkRequest עם אותו שם ייחודי, WorkManager מעדכן אותו מפרט חדש. בהתאם לתהליך העבודה הזה, אין צורך להשתמש updateWork()