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>