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

بالنسبة إلى مستخدمي Kotlin، يقدّم WorkManager دعمًا من الدرجة الأولى للمهام المتعدّدة. للبدء، أدرِج work-runtime-ktx في ملف gradle. بدلاً من تمديد 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>