CoroutineWorker의 스레딩

WorkManager는 Kotlin 사용자에게 코루틴을 위한 최고 수준의 지원을 제공합니다. 시작하려면 gradle 파일에 work-runtime-ktx를 포함해야 합니다. Worker를 확장하는 대신 doWork()의 정지 버전인 CoroutineWorker를 확장해야 합니다. 예를 들어 간단한 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와 달리 이 코드는 Configuration에 지정된 Executor에서 실행되지 않습니다. 대신 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 실행

ListenableWorker의 구현인 RemoteCoroutineWorker를 사용하여 작업자를 특정 프로세스에 바인딩할 수도 있습니다.

RemoteCoroutineWorker는 작업 요청을 작성할 때 입력 데이터의 일부로 제공하는 두 개의 추가 인수 ARGUMENT_CLASS_NAMEARGUMENT_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>

샘플