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