رشته‌بندی در 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.

مثال زیر ساختن درخواست کاری را نشان می‌دهد که به فرایند خاصی محدود شده است:

کاتلین

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()

جاوا

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>