سلسلة المحادثات في CoroutineWorker

لمستخدمي لغة Kotlin، يوفّر WorkManager دعمًا من الدرجة الأولى لبرامج coroutine. للبدء، يمكنك تضمين work-runtime-ktx في ملف Grale. وبدلاً من تمديد فترة Worker، يجب تمديد فترة CoroutineWorker التي تتضمّن إصدار doWork() معلّق. على سبيل المثال، إذا أردت إنشاء رمز CoroutineWorker بسيط لتنفيذ بعض عمليات الشبكة، يمكنك إجراء ما يلي:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        val data = downloadSynchronously("https://www.google.com")
        saveData(data)
        return Result.success()
    }
}

تجدر الإشارة إلى أنّ CoroutineWorker.doWork() إحدى وظائف التعليق. على عكس Worker، لا يعمل هذا الرمز على Executor المحددة في Configuration. بدلاً من ذلك، يتم ضبط القيمة التلقائية على Dispatchers.Default. ويمكنك تخصيص ذلك من خلال تقديم CoroutineContext الخاصة بك. في المثال أعلاه، قد تحتاج إلى تنفيذ هذا الإجراء على Dispatchers.IO، كما يلي:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        withContext(Dispatchers.IO) {
            val data = downloadSynchronously("https://www.google.com")
            saveData(data)
            return Result.success()
        }
    }
}

يعالج CoroutineWorker صفحات الإيقاف تلقائيًا عن طريق إلغاء الكوروتيين ونشر إشارات الإلغاء. ولن تحتاج إلى اتخاذ أي إجراء خاص للتعامل مع صفحات إيقاف العمل.

تشغيل CoroutineWorker في عملية مختلفة

يمكنك أيضًا إلزام العامل بعملية محدّدة باستخدام RemoteCoroutineWorker، وهي تنفيذ ListenableWorker.

ترتبط السمة RemoteCoroutineWorker بعملية محدّدة باستخدام وسيطتين إضافيتين تقدّمهما كجزء من بيانات الإدخال عند إنشاء طلب العمل، وهما: ARGUMENT_CLASS_NAME وARGUMENT_PACKAGE_NAME.

يوضح المثال التالي إنشاء طلب عمل مرتبط بعملية محددة:

Kotlin

val PACKAGE_NAME = "com.example.background.multiprocess"

val serviceName = RemoteWorkerService::class.java.name
val componentName = ComponentName(PACKAGE_NAME, serviceName)

val data: Data = Data.Builder()
   .putString(ARGUMENT_PACKAGE_NAME, componentName.packageName)
   .putString(ARGUMENT_CLASS_NAME, componentName.className)
   .build()

return OneTimeWorkRequest.Builder(ExampleRemoteCoroutineWorker::class.java)
   .setInputData(data)
   .build()

Java

String PACKAGE_NAME = "com.example.background.multiprocess";

String serviceName = RemoteWorkerService.class.getName();
ComponentName componentName = new ComponentName(PACKAGE_NAME, serviceName);

Data data = new Data.Builder()
        .putString(ARGUMENT_PACKAGE_NAME, componentName.getPackageName())
        .putString(ARGUMENT_CLASS_NAME, componentName.getClassName())
        .build();

return new OneTimeWorkRequest.Builder(ExampleRemoteCoroutineWorker.class)
        .setInputData(data)
        .build();

لكل RemoteWorkerService، عليك أيضًا إضافة تعريف خدمة في ملف AndroidManifest.xml:

<manifest ... >
    <service
            android:name="androidx.work.multiprocess.RemoteWorkerService"
            android:exported="false"
            android:process=":worker1" />

        <service
            android:name=".RemoteWorkerService2"
            android:exported="false"
            android:process=":worker2" />
    ...
</manifest>

عيّنات