Threads in CoroutineWorker

Für Kotlin-Nutzer bietet WorkManager erstklassige Unterstützung für Coroutinen. Fügen Sie zum Einstieg work-runtime-ktx in Ihre Gradle-Datei ein. Anstatt Worker zu erweitern, sollten Sie CoroutineWorker erweitern, da es eine Version von doWork() mit Aussetzung gibt. Wenn Sie beispielsweise eine einfache CoroutineWorker zum Ausführen einiger Netzwerkvorgänge erstellen möchten, gehen Sie so vor:

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

Beachten Sie, dass CoroutineWorker.doWork() eine aussetzende Funktion ist. Im Gegensatz zu Worker wird dieser Code nicht auf der in Configuration angegebenen Executor ausgeführt. Stattdessen wird standardmäßig Dispatchers.Default verwendet. Sie können diese Angaben anpassen, indem Sie Ihre eigene CoroutineContext angeben. Im obigen Beispiel würden Sie diese Arbeit wahrscheinlich auf Dispatchers.IO ausführen. Gehen Sie dazu so vor:

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 verarbeitet Unterbrechungen automatisch, indem die Coroutine abgebrochen und die Abbruchsignale weitergegeben werden. Sie müssen nichts Besonderes tun, um Arbeitsunterbrechungen zu verarbeiten.

CoroutineWorker in einem anderen Prozess ausführen

Sie können einen Worker auch mit einem bestimmten Prozess verknüpfen, indem Sie RemoteCoroutineWorker verwenden, eine Implementierung von ListenableWorker.

RemoteCoroutineWorker wird mit zwei zusätzlichen Argumenten an einen bestimmten Prozess gebunden, die Sie beim Erstellen der Arbeitsanfrage als Teil der Eingabedaten angeben: ARGUMENT_CLASS_NAME und ARGUMENT_PACKAGE_NAME.

Das folgende Beispiel zeigt, wie eine Arbeitsanfrage erstellt wird, die an einen bestimmten Prozess gebunden ist:

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

Für jede RemoteWorkerService-Datei müssen Sie auch eine Dienstdefinition in Ihrer AndroidManifest.xml-Datei hinzufügen:

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