בעזרת WorkManager ניתן ליצור ולהעביר שרשרת של עבודה שמציינת מספר משימות תלויות ומגדיר את הסדר שבו הן צריכות לפעול. הזה היא שימושית במיוחד כשצריך להריץ כמה משימות הזמנה מסוימת.
כדי ליצור שרשרת משימות, אפשר להשתמש ב-WorkManager.beginWith(OneTimeWorkRequest)
או ב-WorkManager.beginWith(List<OneTimeWorkRequest>)
, שכל אחת מהן מחזירה מופע של WorkContinuation
.
לאחר מכן אפשר להשתמש ב-WorkContinuation
כדי להוסיף מכונות OneTimeWorkRequest
תלויות באמצעות then(OneTimeWorkRequest)
או then(List<OneTimeWorkRequest>)
.
כל הפעלה של WorkContinuation.then(...)
תחזיר מופע חדש של WorkContinuation
. אם מוסיפים List
של מכונות OneTimeWorkRequest
, הבקשות האלה יכולות לפעול במקביל.
לבסוף, אפשר להשתמש ב-method WorkContinuation.enqueue()
כדי enqueue()
את שרשרת ה-WorkContinuation
.
נבחן עכשיו דוגמה. בדוגמה הזו, 3 משימות שונות של Worker מוגדר לפעול (ופוטנציאלית במקביל). התוצאות של העובדים האלה אחר כך הצטרף והועבר למשימה של עובד שמירה במטמון. לבסוף, הפלט של המשימה מועבר ל-Worker להעלאה, שמעלה את התוצאות לשרת מרוחק.
Kotlin
WorkManager.getInstance(myContext) // Candidates to run in parallel .beginWith(listOf(plantName1, plantName2, plantName3)) // Dependent work (only runs after all previous work in chain) .then(cache) .then(upload) // Call enqueue to kick things off .enqueue()
Java
WorkManager.getInstance(myContext) // Candidates to run in parallel .beginWith(Arrays.asList(plantName1, plantName2, plantName3)) // Dependent work (only runs after all previous work in chain) .then(cache) .then(upload) // Call enqueue to kick things off .enqueue();
מיזוגי קלט
כשמחברים יחד מכונות OneTimeWorkRequest
, הפלט של בקשות העבודה של ההורה מועבר כקלט לצאצאים. בדוגמה שלמעלה,
הפלט של plantName1
, plantName2
ו-plantName3
יועבר כ-
קלט לבקשת cache
.
כדי לנהל את הקלטות ממספר בקשות הורה, WorkManager משתמש ב-InputMerger
.
יש שני סוגים שונים של InputMerger
ש-WorkManager מספק:
OverwritingInputMerger
מנסים להוסיף את כל המפתחות מכל מקורות הקלט לתוצאה. במקרה של התנגשויות, הוא מחליף את המפתחות שהוגדרו קודם.ArrayCreatingInputMerger
versucht, die Eingaben zu verschmelzen und Arrays zu erstellen, wenn nötig.
אם יש לכם תרחיש לדוגמה ספציפי יותר, תוכלו לכתוב תרחיש משלכם על ידי יצירה של תת-מחלקה של InputMerger
.
OverwritingInputMerger
OverwritingInputMerger
היא שיטת המיזוג שמוגדרת כברירת מחדל. אם יש מפתח
במיזוג, אז הערך האחרון של מפתח יחליף כל
מהגרסאות הקודמות בנתוני הפלט שהתקבלו.
לדוגמה, אם לכל אחד מהקלטים של הצמח יש מפתח שמתאים לשמות המשתנים המתאימים ("plantName1"
, "plantName2"
ו-"plantName3"
), הנתונים שיועברו לעובד cache
יכללו שלושה זוגות של מפתח/ערך.
אם יש מחלוקת, העובד האחרון שהשלים את ה'מנצח' והערך שלו
מועבר אל cache
.
מאחר שבקשות העבודה שלך פועלות במקביל, אין לך אפשרות להבטיח
סדר ההפעלה שלו. בדוגמה שלמעלה, הערך של plantName1
יכול להיות "tulip"
או "elm"
, בהתאם לערך שנכתב אחרון. אם יש סיכוי לסכסוך מפתחות ואתם צריכים לשמור את כל נתוני הפלט במיזוג, ArrayCreatingInputMerger
עשויה להיות אפשרות טובה יותר.
ArrayCreatingInputMerger
בדוגמה שלמעלה, מכיוון שאנחנו רוצים לשמור את הפלט מכל העובדים של plantname, צריך להשתמש ב-ArrayCreatingInputMerger
.
Kotlin
val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>() .setInputMerger(ArrayCreatingInputMerger::class) .setConstraints(constraints) .build()
Java
OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class) .setInputMerger(ArrayCreatingInputMerger.class) .setConstraints(constraints) .build();
ArrayCreatingInputMerger
מתאים כל מפתח למערך. אם כל אחד מהמפתחות
היא ייחודית, אז התוצאה היא סדרה של מערכים של רכיב אחד.
אם יש התנגשויות בין מפתחות, הערכים התואמים מקובצים יחד במערך.
סטטוסים של שרשורים ועבודה
שרשראות של OneTimeWorkRequest
פועלות ברצף כל עוד העבודה שלהן מסתיימת בהצלחה (כלומר, הן מחזירות Result.success()
). בקשות עבודה עשויות להיכשל או להתבטל במהלך ההרצה, ויש לכך השפעה על בקשות עבודה תלויות.
כשה-OneTimeWorkRequest
הראשון נוסף לתור בשרשרת של בקשות עבודה,
כל בקשות העבודה הבאות חסומות עד לעבודה של אותה עבודה ראשונה
הבקשה הושלמה.
אחרי שהבקשה נכנסת לתור וכל אילוצי העבודה מתקיימים, היא מתחילה לפעול. אם העבודה הושלמה בהצלחה ברמה הבסיסית OneTimeWorkRequest
או List<OneTimeWorkRequest>
(כלומר, היא מחזירה Result.success()
), המערכת תוסיף לתור את הקבוצה הבאה של בקשות העבודה התלויות.
כל עוד כל בקשת עבודה מסתיימת בהצלחה, אותו דפוס מופץ לשאר שרשרת בקשות העבודה עד שכל העבודה בשרשרת מסתיימת. אומנם זה המקרה הפשוט ביותר, ולרוב הוא מועדף, אבל חשוב לטפל בהן באותה מידה.
אם מתרחשת שגיאה בזמן שעובד מעבד את בקשת העבודה, תוכלו לנסות שוב את הבקשה בהתאם למדיניות ההשהיה לפני ניסיון חוזר (backoff) שתגדירו. ניסיון חוזר של בקשה שהיא חלק משרשרת פירושו שרק הבקשה הזו לנסות שוב עם נתוני הקלט שסופקו לו. כל עבודה שתפעל במקביל לא יושפעו.
למידע נוסף על הגדרת אסטרטגיות מותאמות אישית של ניסיונות חוזרים, אפשר לעיין במאמר ניסיון חוזר והשהיה לפני ניסיון חוזר (backoff) מדיניות.
אם המדיניות בנושא ניסיונות חוזרים לא מוגדרת או נוצלה במלואה, או אם מגיעים לחלק
שבו OneTimeWorkRequest
מחזירה Result.failure()
, אז
בקשת העבודה וכל בקשות העבודה התלויות מסומנות כ-FAILED.
אותה לוגיקה חלה גם במקרה של ביטול של OneTimeWorkRequest
. גם בקשות עבודה תלויות מסומנות ב-CANCELLED
, והעבודה שלהן לא תבוצע.
חשוב לזכור: אם תצרפו בקשות עבודה נוספות לרשת שנכשלה או לבקשות עבודה שבוטלו, גם בקשת העבודה החדשה שתצרפו תסומן ב-FAILED
או ב-CANCELLED
, בהתאמה. כדי להרחיב את העבודה של שרשרת קיימת, אפשר לעיין ב-APPEND_OR_REPLACE
בקטע ExistingWorkPolicy.
כשיוצרים שרשראות של בקשות עבודה, צריך להגדיר בקשות עבודה תלויות כללי מדיניות לביצוע ניסיונות חוזרים כדי להבטיח שהעבודה תמיד תתבצע בזמן. בקשות עבודה שנכשלו עלולות לגרום לשרשראות לא שלמות או למצב לא צפוי.
מידע נוסף זמין במאמר ביטול והפסקה של משימות.