Pour les utilisateurs de Kotlin, WorkManager offre une prise en charge de premier ordre pour les coroutines. Pour commencer, incluez work-runtime-ktx
dans votre fichier Gradle. Au lieu de Worker
, vous devez étendre CoroutineWorker
, qui possède une version de suspension de doWork()
. Par exemple, si vous souhaitez créer un CoroutineWorker
simple pour effectuer certaines opérations réseau, procédez comme suit :
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()
}
}
Notez que CoroutineWorker.doWork()
est une fonction de suspension. Contrairement à Worker
, ce code ne s'exécute pas sur l'Executor
spécifié dans votre Configuration
. Au lieu de cela, il est défini par défaut sur Dispatchers.Default
. Vous pouvez personnaliser cette fonction en fournissant votre propre CoroutineContext
. Dans l'exemple ci-dessus, vous souhaiterez probablement effectuer cette tâche sur Dispatchers.IO
, comme suit :
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
gère automatiquement les arrêts en annulant la coroutine et en propageant les signaux d'annulation. Aucune action spéciale n'est requise pour gérer les arrêts de tâches.
Exécuter un CoroutineWorker dans un processus différent
Vous pouvez également lier un nœud de calcul à un processus spécifique à l'aide de RemoteCoroutineWorker
: une implémentation de ListenableWorker
.
RemoteCoroutineWorker
se lie à un processus spécifique avec deux arguments supplémentaires que vous fournissez dans les données d'entrée lors de la création de la requête de tâche : ARGUMENT_CLASS_NAME
et ARGUMENT_PACKAGE_NAME
.
L'exemple suivant illustre la création d'une requête de tâche liée à un processus spécifique :
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();
Pour chaque RemoteWorkerService
, vous devez également ajouter une définition de service dans votre fichier 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>