تتيح لك 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 مختلفة ليتم تنفيذها (ربما بالتوازي). يتم بعد ذلك دمج نتائج هؤلاء العاملين وتمريرها إلى مهمة عامل التخزين المؤقت. أخيرًا، يتم تمرير ناتج هذه المهمة إلى عامل تحميل (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
في المثال أعلاه، بما أنّنا نريد الاحتفاظ بالنتائج من جميع عناصر Worker التي تحمل اسم نبات، يجب استخدام 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.
عند إنشاء سلاسل من طلبات العمل، يجب أن تحدّد طلبات العمل التابعة سياسات إعادة المحاولة لضمان إكمال العمل دائمًا في الوقت المناسب. قد تؤدي طلبات العمل الفاشلة إلى سلاسل غير مكتملة و/أو حالة غير متوقّعة.
لمزيد من المعلومات، يُرجى الاطّلاع على إلغاء العمل وإيقافه.