Para usuários do Kotlin, o WorkManager oferece compatibilidade de primeira classe com corrotinas. Para
começar, inclua work-runtime-ktx
no arquivo do Gradle. Em vez de estender Worker
, estenda CoroutineWorker
, que tem uma versão
de suspensão de doWork()
. Por exemplo, se você quiser criar um CoroutineWorker
simples para executar algumas operações de rede, faça o seguinte:
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()
}
}
Observe que CoroutineWorker.doWork()
é uma função
de suspensão. Ao contrário de Worker
, esse código não é executado no Executor
especificado
na Configuration
. Em vez disso,
o padrão é Dispatchers.Default
. Você pode personalizar isso fornecendo seu próprio CoroutineContext
. No exemplo acima, você provavelmente faria esse trabalho em Dispatchers.IO
, da seguinte forma:
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
processa as interrupções automaticamente, cancelando a corrotina
e propagando os sinais de cancelamento. Você não precisa fazer nada especial
para processar as interrupções de trabalho.
Como executar um CoroutineWorker em um processo diferente
Também é possível vincular um worker a um processo específico usando
RemoteCoroutineWorker
,
uma implementação de ListenableWorker
.
RemoteCoroutineWorker
se vincula a um processo específico com dois argumentos
extras que você fornece como parte dos dados de entrada ao criar a solicitação
de trabalho: ARGUMENT_CLASS_NAME
e ARGUMENT_PACKAGE_NAME
.
O exemplo a seguir demonstra a criação de uma solicitação de trabalho vinculada a um processo específico:
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();
Para cada RemoteWorkerService
, também é preciso adicionar uma definição de serviço no
arquivo 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>
Exemplos
- WorkManagerMultiProcessSample (link em inglês)