تعديل العمل الذي تمت إضافته إلى قائمة الانتظار بالفعل

يسمح لك WorkManager بتعديل عنصر WorkRequest بعد إضافته إلى قائمة الانتظار. هذا الإجراء ضروري غالبًا في التطبيقات الكبيرة التي تغيّر القيود أو تحتاج إلى تحديث العاملين بشكل فوري. واعتبارًا من الإصدار 2.8.0 من WorkManager، أصبحت واجهة برمجة التطبيقات updateWork() هي الوسيلة اللازمة لإجراء ذلك.

تتيح لك الطريقة updateWork() تغيير جوانب معيّنة في WorkRequest بسرعة، بدون الحاجة إلى إجراء عملية الإلغاء يدويًا وإدراج عنصر جديد في قائمة المحتوى التالي. وهذا يبسط عملية التطوير بشكل كبير.

تجنب إلغاء العمل

يجب أن تتجنب بشكل عام إلغاء طلب عمل حالي وإضافة طلب جديد إلى قائمة الانتظار. قد يؤدي ذلك إلى تكرار التطبيق لمهام معينة، وقد يتطلب منك كتابة قدر كبير من التعليمات البرمجية الإضافية.

ضع في اعتبارك الأمثلة التالية حول المواضع التي قد يؤدي فيها إلغاء WorkRequest إلى حدوث صعوبات:

  • طلب خلفية: في حال إلغاء Worker أثناء احتساب حمولة البيانات لإرسالها إلى الخادم، يجب بدء Worker الجديد من جديد وإعادة حساب الحمولات التي يُحتمل أن تكون باهظة الثمن.
  • الجدولة: إذا ألغيت PeriodicWorkRequest وكنت تريد تنفيذ PeriodicWorkRequest الجديد وفقًا للجدول الزمني نفسه، عليك احتساب معادلة زمنية لضمان توافق وقت التنفيذ الجديد مع طلب العمل السابق.

تتيح لك واجهة برمجة التطبيقات updateWork() تعديل القيود المفروضة على طلب العمل والمَعلمات الأخرى بدون الحاجة إلى إلغاء طلب جديد أو إضافته إلى قائمة الانتظار.

متى يتم إلغاء العمل

في بعض الحالات، يجب عليك إلغاء WorkRequest مباشرةً بدلاً من الاتصال بـ updateWork(). هذا ما يجب عليك فعله عندما ترغب في تغيير الطبيعة الأساسية للعمل الذي أضفته إلى قائمة الانتظار.

موعد تعديل الملف الشخصي للعمل

تخيل أن تطبيق الصور يقوم بعمل نسخة احتياطية يومية من صور المستخدم. وتمت إضافة PeriodicWorkRequest إلى قائمة الانتظار لإجراء ذلك. يُرجى العِلم أنّ الحقل WorkRequest يفرض قيودًا تتطلّب شحن الجهاز ومتصلاً بشبكة WiFi.

ومع ذلك، لا يشحن المستخدم جهازه إلا لمدة 20 دقيقة يوميًا باستخدام شاحن سريع. في هذه الحالة، قد يحتاج التطبيق إلى تحديث WorkRequest لتخفيف قيد الشحن، بحيث لا يزال بإمكانه تحميل الصور حتى إذا لم يكن الجهاز مشحونًا بالكامل.

في هذه الحالة، يمكنك استخدام الطريقة updateWork() لتعديل قيود طلب العمل.

كيفية تعديل قائمة العمل

توفّر طريقة updateWork() وسيلة بسيطة لتعديل WorkRequest حالي، بدون الحاجة إلى إلغاء إضافة جديدة إلى قائمة الانتظار.

لاستخدام العمل المدرج في قائمة التحديث، اتّبِع الخطوات التالية:

  1. الحصول على المعرّف الحالي للعمل في قائمة الانتظار: احصل على معرّف WorkRequest الذي تريد تعديله. يمكنك استرداد رقم التعريف هذا باستخدام أي من واجهات برمجة تطبيقات getWorkInfo، أو من خلال الاحتفاظ بالمعرّف يدويًا من طلب WorkRequest الأول لاسترداده لاحقًا باستخدام الموقع العام WorkRequest.id، قبل إضافته إلى قائمة المحتوى التالي.
  2. إنشاء WorkRequest جديد: أنشِئ WorkRequest جديدة واستخدِم WorkRequest.Builder.setID() لضبط معرّفه لمطابقة معرّف WorkRequest الحالي.
  3. ضبط القيود: استخدِم WorkRequest.Builder.setConstraints() لتمرير قيود جديدة في WorkManager.
  4. Call updateWork: مرِّر WorkRequest الجديد إلى updateWork().

تعديل مثال على العمل

في ما يلي مثال لمقتطف الرمز في Kotlin يوضح كيفية استخدام طريقة updateWork() لتغيير قيود البطارية في WorkRequest المستخدمة لتحميل الصور:

suspend fun updatePhotoUploadWork() {
    // Get instance of WorkManager.
    val workManager = WorkManager.getInstance(context)

    // Retrieve the work request ID. In this example, the work being updated is unique
    // work so we can retrieve the ID using the unique work name.
    val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
        PHOTO_UPLOAD_WORK_NAME
    ).await()

    val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return

    // Update the constraints of the WorkRequest to not require a charging device.
    val newConstraints = Constraints.Builder()
        // Add other constraints as required here.
        .setRequiresCharging(false)
        .build()

    // Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
    val updatedWorkRequest: WorkRequest =
        OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(newConstraints)
            .setId(existingWorkRequestId)
            .build()

    // Pass the new WorkRequest to updateWork().
    workManager.updateWork(updatedWorkRequest)
}

التعامل مع النتيجة

تعرض الدالة updateWork() القيمة ListenableFuture<UpdateResult>. يمكن أن يحتوي UpdateResult المحدّد على إحدى القيم العديدة التي تحدّد ما إذا تمكّن WorkManager من تطبيق التغييرات أم لا. كما يشير أيضًا إلى الوقت الذي تمكن فيه من تطبيق التغيير.

لمزيد من المعلومات، يمكنك الاطّلاع على updateWork() و UpdateResult المرجع.

تتبُّع العمل مع الأجيال

في كل مرة يتم فيها تعديل WorkRequest، يزداد إنشاءه بمقدار واحد. يتيح لك ذلك تتبُّع WorkRequest بالضبط في قائمة الانتظار. تمنحك الأجيال مزيدًا من التحكم عند مراقبة طلبات العمل وتتبّعها واختبارها.

لإنشاء WorkRequest، يُرجى اتّباع الخطوات التالية:

  1. WorkInfo: استدعِ WorkManager.getWorkInfoById() لاسترداد مثيل WorkInfo المقابل لـ WorkRequest.
    • يمكنك استدعاء إحدى الطرق المتعددة التي تعرض WorkInfo. لمزيد من المعلومات، يُرجى الاطّلاع على مرجع WorkManager.
  2. getGeneration: يمكنك الاتصال بـ getGeneration() على مثال WorkInfo. ويتوافق Int الذي يتم عرضه مع إنشاء WorkRequest.
    • يُرجى العِلم أنّه لا يوجد حقل أو خاصية لإنشاء، بل الطريقة WorkInfo.getGeneration() فقط.

مثال على إنشاء المسار

فيما يلي مثال على تنفيذ سير العمل الموضّح أعلاه لاسترداد إنشاء WorkRequest.

// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)

// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)

// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()

سياسات تعديل العمل

في السابق، كان الحل المقترَح لتعديل العمل الدوري هو إضافة PeriodicWorkRequest إلى قائمة الانتظار مع السياسة ExistingPeriodicWorkPolicy.REPLACE. إذا كان هناك طلب عمل PeriodicWorkRequest في انتظار المراجعة يتضمّن السمة id الفريدة نفسها، سيتم إلغاؤه وحذفه في طلب العمل الجديد. تم إيقاف هذه السياسة الآن لصالح سير العمل باستخدام ExistingPeriodicWorkPolicy.UPDATE.

على سبيل المثال، عند استخدام enqueueUniquePeriodicWork مع PeriodicWorkRequest، يمكنك إعداد PeriodicWorkRequest الجديد باستخدام سياسة ExistingPeriodicWorkPolicy.UPDATE. في حال وجود PeriodicWorkRequest في انتظار المراجعة بالاسم الفريد نفسه، يعدّل WorkManager إلى المواصفات الجديدة. بعد سير العمل هذا، ليس من الضروري استخدام updateWork().