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