Tworzenie wątków w CoroutineWorker

Użytkownicy Kotlin mogą korzystać z WorkManagera na najwyższym poziomie do obsługi współrzędnych. Aby uzyskać dołącz work-runtime-ktx do pliku Gradle. Zamiast przedłużać subskrypcję Worker, wydłuż CoroutineWorker, co wiąże się z zawieszeniem wersję doWork(). Jeśli na przykład chcesz utworzyć prosty CoroutineWorker aby wykonać pewne operacje sieciowe, wykonaj te czynności:

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

Pamiętaj, że CoroutineWorker.doWork() jest zawieszonym . W przeciwieństwie do Worker ten kod nie działa w określonym miejscu (Executor) w Configuration. Zamiast tego domyślna wartość to Dispatchers.Default. Możesz go dostosować, podając własne CoroutineContext. W powyższym przykładzie wszystkie zmiany powinny zostać wykonane na Dispatchers.IO w ten sposób:

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 automatycznie obsługuje zatrzymania, anulując współprogram i rozpowszechnianie sygnałów anulowania. Nie musisz robić nic szczególnego obsługi zatrzymań zadań.

Uruchamianie elementu CoroutineWorker w innym procesie

Możesz też powiązać instancję roboczą z konkretnym procesem za pomocą polecenia RemoteCoroutineWorker implementacją ListenableWorker.

Funkcja RemoteCoroutineWorker wiąże się z określonym procesem za pomocą 2 dodatkowych argumentów którą podajesz jako część danych wejściowych podczas tworzenia zlecenia: ARGUMENT_CLASS_NAME i ARGUMENT_PACKAGE_NAME.

Poniższy przykład pokazuje tworzenie żądania pracy, które jest powiązane z konkretny proces:

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

W przypadku każdego elementu (RemoteWorkerService) musisz też dodać definicję usługi w: Twój plik 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>

Próbki