Per gli utenti di Kotlin, WorkManager fornisce un'assistenza di primo livello per le coroutine. Per iniziare, includi work-runtime-ktx nel file Gradle. Anziché estendere Worker, devi estendere CoroutineWorker, che ha una versione in sospensione di doWork(). Ad esempio, se vuoi creare un semplice CoroutineWorker
per eseguire alcune operazioni di rete, devi procedere nel seguente modo:
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()
}
}
Tieni presente che CoroutineWorker.doWork() è una funzione di sospensione. A differenza di Worker, questo codice non viene eseguito sul Executor specificato
nel tuo Configuration. Al suo posto, viene utilizzato il valore predefinito Dispatchers.Default. Puoi personalizzarlo fornendo il tuo CoroutineContext. Nell'esempio precedente, probabilmente vorrai eseguire questa operazione su Dispatchers.IO, come segue:
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 gestisce automaticamente gli arresti annullando la coroutine
e propagando gli indicatori di annullamento. Non devi fare nulla di speciale per gestire gli interruzioni del lavoro.
Esecuzione di un CoroutineWorker in un processo diverso
Puoi anche associare un worker a un processo specifico utilizzando
RemoteCoroutineWorker,
un'implementazione di ListenableWorker.
RemoteCoroutineWorker si lega a un processo specifico con due argomenti aggiuntivi
che fornisci come parte dei dati di input durante la creazione della richiesta di lavoro:
ARGUMENT_CLASS_NAME e ARGUMENT_PACKAGE_NAME.
L'esempio seguente mostra la creazione di una richiesta di lavoro associata a un procedura specifica:
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();
Per ogni RemoteWorkerService, devi anche aggiungere una definizione di servizio nel
file 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>