Este documento explica como migrar apps para a biblioteca de cliente do WorkManager a fim de executar operações em segundo plano, em vez de usar a biblioteca do GCMNetworkManager. A maneira preferencial de um app programar jobs em segundo plano é usar o WorkManager. Ao incluir também a biblioteca GCM do WorkManager, você pode permitir que o WorkManager use o GCM para programar tarefas durante a execução em dispositivos Android com API de nível 22 ou versões mais antigas.
Migrar para o WorkManager
Se o app usa atualmente o GCMNetworkManager para realizar operações em segundo plano, siga estas etapas para migrar para o WorkManager.
Nas etapas a seguir, presumimos que você esteja começando com o seguinte código GCMNetworkManager, que define e programa sua tarefa:
Kotlin
val myTask = OneoffTask.Builder() // setService() says what class does the work .setService(MyUploadService::class.java) // Don't run the task unless device is charging .setRequiresCharging(true) // Run the task between 5 & 15 minutes from now .setExecutionWindow(5 * DateUtil.MINUTE_IN_SECONDS, 15 * DateUtil.MINUTE_IN_SECONDS) // Define a unique tag for the task .setTag("test-upload") // ...finally, build the task and assign its value to myTask .build() GcmNetworkManager.getInstance(this).schedule(myTask)
Java
// In GcmNetworkManager, this call defines the task and its // runtime constraints: OneoffTask myTask = new OneoffTask.Builder() // setService() says what class does the work .setService(MyUploadService.class) // Don't run the task unless device is charging .setRequiresCharging(true) // Run the task between 5 & 15 minutes from now .setExecutionWindow( 5 * DateUtil.MINUTE_IN_SECONDS, 15 * DateUtil.MINUTE_IN_SECONDS) // Define a unique tag for the task .setTag("test-upload") // ...finally, build the task and assign its value to myTask .build(); GcmNetworkManager.getInstance(this).schedule(myTask);
Neste exemplo, supomos que MyUploadService
define a operação de upload real:
Kotlin
class MyUploadService : GcmTaskService() { fun onRunTask(params: TaskParams): Int { // Do some upload work return GcmNetworkManager.RESULT_SUCCESS } }
Java
class MyUploadService extends GcmTaskService { @Override public int onRunTask(TaskParams params) { // Do some upload work return GcmNetworkManager.RESULT_SUCCESS; } }
Incluir as bibliotecas do WorkManager
Para usar as classes do WorkManager, você precisa adicionar a biblioteca do WorkManager às suas dependências de compilação. Você também precisa adicionar a biblioteca GCM do WorkManager, que permite que o WorkManager use o GCM para programar jobs quando o app está em execução em dispositivos não compatíveis com o JobScheduler (ou seja, dispositivos com API de nível 22 ou versões mais antigas). Para ver mais detalhes sobre como adicionar as bibliotecas, consulte Primeiros passos com o WorkManager.
Modificar o manifesto
Ao implementar o GCMNetworkmanager, você adicionou uma instância de
GcmTaskService
ao manifesto do app, conforme descrito na documentação de referência
do GcmNetworkManager
.
GcmTaskService
analisa a tarefa recebida e a delega ao gerenciador de
tarefas. O WorkManager gerencia a delegação de tarefas para o worker. Assim, você não precisa
mais de uma classe para fazer isso. Basta remover GcmTaskService
do
manifesto.
Definir o worker
Sua implementação do GCMNetworkManager define uma OneoffTask
ou RecurringTask
,
que especifica apenas que trabalho precisa ser feito. É necessário reescrever isso como um
Worker
, conforme documentado em Como definir suas solicitações
de trabalho.
O código GCMNetworkManager
de amostra
define uma tarefa myTask
. O equivalente ao WorkManager é semelhante a este:
Kotlin
class UploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork() : Result { // Do the upload operation ... myUploadOperation() // Indicate whether the task finished successfully with the Result return Result.success() } }
Java
public class UploadWorker extends Worker { public UploadWorker( @NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @Override public Result doWork() { // Do the upload operation ... myUploadOperation() // Indicate whether the task finished successfully with the Result return Result.success() } }
Há algumas diferenças entre a tarefa do GCM e o Worker
:
- O GCM usa um objeto
TaskParams
para transmitir parâmetros para a tarefa. OWorkManager
usa dados de entrada, que você pode especificar naWorkRequest
, conforme descrito na documentação doWorkManager
para Definir entrada/saída para sua tarefa. Em ambos os casos, você pode transmitir pares de chave-valor especificando os parâmetros persistentes necessários para a tarefa. - O
GcmTaskService
indica sucesso ou falha retornando sinalizações comoGcmNetworkManager.RESULT_SUCCESS
. UmWorker
do WorkManager sinaliza os resultados usando um métodoListenableWorker.Result
, comoListenableWorker.Result.success()
, e retornando o valor de retorno desse método. - Como mencionamos, você não define as restrições ou tags ao definir o
Worker
, mas faz isso na próxima etapa, ao criar aWorkRequest
.
Programar a solicitação de trabalho
Definir um Worker
especifica o que é necessário fazer. Para especificar quando o trabalho
será feito, é necessário definir a
WorkRequest
:
- Crie uma
OneTimeWorkRequest
ouPeriodicWorkRequest
e defina as restrições desejadas especificando quando a tarefa será executada, bem como as tags para identificar seu trabalho. - Transmita a solicitação a
WorkManager.enqueue()
para que a tarefa fique na fila para execução.
Por exemplo, a seção anterior mostrou como converter uma
OneoffTask
em um Worker
equivalente. No entanto, esse Worker
não incluiu as restrições de execução e a tag do objeto OneoffTask
. Em vez disso, definimos as
restrições e o ID da tarefa quando criamos a WorkRequest
. Também especificaremos que a tarefa
só poderá ser executada se houver uma conexão de rede. Você não precisa solicitar
explicitamente uma conexão de rede com o GCMNetworkManager, porque ele
requer essa conexão por padrão. O WorkManager só requer uma
conexão de rede quando você adiciona especificamente essa restrição.
Depois de definir a WorkRequest
, nós a colocamos na fila com o WorkManager.
Kotlin
val uploadConstraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true).build() val uploadTask = OneTimeWorkRequestBuilder<UploadWorker>() .setConstraints(uploadConstraints) .build() WorkManager.getInstance().enqueue(uploadTask)
Java
Constraints uploadConstraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true) .build(); OneTimeWorkRequest uploadTask = new OneTimeWorkRequest.Builder(UploadWorker.class) .setConstraints(uploadConstraints) .build(); WorkManager.getInstance().enqueue(uploadTask);
Mapeamentos de API
Esta seção faz um mapeamento de como alguns recursos e restrições do GCMNetworkManager são equivalentes aos do WorkManager.
Mapeamentos de restrições
O GCMNetworkManager permite que você defina várias restrições relativas a quando sua tarefa será executada. Na maioria dos casos, há uma restrição do WorkManager equivalente. Esta seção lista os equivalentes.
Defina restrições para as tarefas do GCMNetworkManager chamando o método apropriado no
objeto Builder da tarefa. Por exemplo, você pode definir um requisito de rede chamando
Task.Builder.setRequiredNetwork()
.
No WorkManager, você cria um
objeto Constraints.Builder
e
chama os métodos dele para definir restrições, por exemplo,
Constraints.Builder.setRequiredNetworkType())
.
Em seguida, usa o Builder para criar um objeto Constraints que pode ser anexado à
solicitação de trabalho. Para ver mais informações, consulte Como definir suas solicitações
de trabalho.
Restrição do GCMNetworkManager | Equivalente do WorkManager | Observações |
---|---|---|
setPersisted() |
Não obrigatório | Todos os jobs do WorkManager são mantidos durante a reinicialização do dispositivo. |
setRequiredNetwork() |
setRequiredNetworkType() |
Por padrão, o GCMNetworkManager requer acesso à rede. Por padrão, o WorkManager não requer acesso à rede. Se o job exigir acesso à rede, use setRequiredNetworkType(CONNECTED) ou defina um tipo de rede mais específico. |
setRequiresCharging() |
Outros mapeamentos
Além das restrições, há outras configurações que você pode aplicar às tarefas do GCMNetworkManager. Esta seção lista a maneira correspondente de aplicar essas configurações a um job do WorkManager.
Tags
Todas as tarefas do GCMNetworkManager precisam ter uma string de tag, que você define chamando o método
setTag()
do Builder. Os jobs do WorkManager são identificados de forma exclusiva por um ID
gerado automaticamente pelo WorkManager. É possível receber esse ID chamando
WorkRequest.getId()
. Além
disso, as solicitações de trabalho podem ter uma ou mais tags. Para definir uma tag para
o job do WorkManager, chame o método
WorkRequest.Builder.addTag()
antes de usar esse Builder para criar a WorkRequest
.
No GCMNetworkManager, é possível chamar
setUpdateCurrent()
para especificar se a tarefa precisa substituir qualquer tarefa existente com a mesma tag.
A abordagem equivalente do WorkManager é colocar a tarefa em fila chamando
enqueueUniqueWork()
ou enqueueUniquePeriodicWork()
.
Se você usar esses métodos, dê um nome exclusivo ao job e especifique como o
WorkManager processará a solicitação quando já houver um job pendente com esse
nome. Para ver mais informações, consulte Como gerenciar um trabalho
exclusivo.
Parâmetros da tarefa
É possível transmitir parâmetros para um job do GCMNetworkManager chamando
Task.Builder.setExtras()
e transmitindo um Bundle
que contenha os parâmetros. O WorkManager permite que você transmita
um objeto Data
para o job do WorkManager,
com os parâmetros como pares de chave-valor. Para mais detalhes, consulte
Atribuir dados de entrada.