Threading در 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>

نمونه ها