يتيح لك WorkManager إنشاء سلسلة مهام وإضافة هذه السلسلة إلى "قائمة الانتظار"، مع تحديد مهام متعددة مترابطة وتحديد الترتيب الذي يجب تنفيذها به. تكون هذه الميزة مفيدة بشكل خاص عندما تحتاج إلى تنفيذ عدة مهام بترتيب معيّن.
لإنشاء سلسلة من الأعمال، يمكنك استخدام
WorkManager.beginWith(OneTimeWorkRequest)
أو
WorkManager.beginWith(List<OneTimeWorkRequest>)
، وكلاهما يعرض مثيلًا من
WorkContinuation
.
يمكن بعد ذلك استخدام WorkContinuation
لإضافة مثيلات OneTimeWorkRequest
تابعة باستخدام
then(OneTimeWorkRequest)
أو
then(List<OneTimeWorkRequest>)
.
يؤدي كلّ استدعاء لـ WorkContinuation.then(...)
إلى عرض مثيل جديد من WorkContinuation
. في حال إضافة List
من مثيلات OneTimeWorkRequest
، يمكن تنفيذ هذه الطلبات بشكل موازٍ.
أخيرًا، يمكنك استخدام الأسلوب
WorkContinuation.enqueue()
لenqueue()
سلسلة WorkContinuation
.
لنلقِ نظرة على مثال. في هذا المثال، تم إعداد 3 مهام مختلفة لعامل لبدء التنفيذ (ربما بشكل موازٍ). بعد ذلك، يتم دمج نتائج "العمال" هذه ونقلها إلى وظيفة "عامل" لتخزين البيانات المؤقتة. أخيرًا، يتم تمرير ناتج هذه الوظيفة إلى 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
دمج الإدخالات، وإنشاء صفائف عند الضرورة.
إذا كانت لديك حالة استخدام أكثر تحديدًا، يمكنك كتابة حالة استخدام خاصة بك من خلال إنشاء فئة فرعية من
InputMerger
.
OverwritingInputMerger
OverwritingInputMerger
هي طريقة الدمج التلقائية. في حال حدوث تعارضات في دمج مفاتيح، ستحلّ أحدث قيمة للمفتاح محلّ أي إصدارات سابقة في بيانات الإخراج الناتجة.
على سبيل المثال، إذا كانت مدخلات المحطة تحتوي كلٌّ منها على مفتاح يتطابق مع
أسماء المتغيّرات المتعلّقة بها ("plantName1"
و"plantName2"
و"plantName3"
)، ستكون
البيانات التي تم تمريرها إلى عامل cache
تحتوي على ثلاث أزواج من المفتاح والقيمة.
في حال حدوث تعارض، يفوز العامل الأخير الذي أكمل المهمة، ويتم تمرير قيمته
إلى cache
.
بما أنّه يتم تنفيذ طلبات العمل بشكل موازٍ، لا تتوفّر لديك ضمانات بشأن
الترتيب الذي يتم تنفيذها به. في المثال أعلاه، يمكن أن يحتوي plantName1
على قيمة
"tulip"
أو "elm"
، بناءً على القيمة التي يتم كتابتها
أخيرًا. إذا كانت هناك احتمالية حدوث تعارض في المفاتيح وكنت بحاجة إلى الاحتفاظ بجميع بيانات المخرجات
في عملية الدمج، قد يكون ArrayCreatingInputMerger
خيارًا أفضل.
ArrayCreatingInputMerger
في المثال أعلاه، بما أنّنا نريد الاحتفاظ بالنواتج من جميع عمال
اسم المصنع، يجب استخدام 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()
)، سيتم
إضافة المجموعة التالية من طلبات العمل التابعة إلى "قائمة الانتظار".
ما دام كل طلب عمل ينتهي بنجاح، يتم تطبيق هذا النمط نفسه على بقية سلسلة طلبات العمل إلى أن تكتمل كل الأعمال في السلسلة. على الرغم من أنّ هذا هو أبسط الحالات وغالبًا ما يكون الخيار المفضّل، إلا أنّه من المهمّ أيضًا التعامل مع حالات الخطأ.
عندما يحدث خطأ أثناء معالجة عامل لطلب العمل، يمكنك إعادة محاولة تنفيذ هذا الطلب وفقًا لسياسة التراجع التي تعيّنها. يعني إعادة محاولة طلب يشكّل جزءًا من سلسلة أنّه سيتم فقط إعادة محاولة هذا الطلب باستخدام بيانات الإدخال المقدَّمة له. ولن تتأثر أي أعمال يتم تنفيذها بشكل موازٍ.
لمزيد من المعلومات عن تحديد استراتيجيات إعادة المحاولة المخصّصة، اطّلِع على سياسة إعادة المحاولة والانتظار.
إذا لم يتم تحديد سياسة إعادة المحاولة هذه أو تم استنفادها، أو إذا وصلت إلى حالة
يعرض فيها OneTimeWorkRequest
القيمة Result.failure()
، يتم وضع علامة FAILED.
على
طلب العمل هذا وجميع طلبات العمل التابعة له.
ينطبق المنطق نفسه عند إلغاء OneTimeWorkRequest
. يتم أيضًا وضع علامة CANCELLED
على أي طلبات عمل تابعة، ولن يتم تنفيذ عملها.
يُرجى العِلم أنّه في حال إلحاق المزيد من طلبات العمل بسلسلة تعذّر إكمالها أو
تم إلغاء طلبات العمل فيها، سيتم أيضًا وضع علامةFAILED
أوCANCELLED
على طلب العمل المُلحَق حديثًا، على التوالي. إذا كنت تريد تمديد العمل
بسلسلة حالية، اطّلِع على APPEND_OR_REPLACE
في
ExistingWorkPolicy.
عند إنشاء سلاسل من طلبات العمل، يجب أن تحدِّد طلبات العمل المُعتمَدة سياسات إعادة المحاولة لضمان إكمال العمل في الوقت المناسب دائمًا. قد تؤدي طلبات العمل غير الناجحة إلى سلاسل غير مكتملة و/أو حالة غير متوقّعة.
لمزيد من المعلومات، يُرجى الاطّلاع على إلغاء العمل وإيقافه.