Participe do evento ⁠#Android11: apresentação de lançamento da versão Beta no dia 3 de junho.

Como definir WorkRequests

O guia de primeiros passos abordou como criar um WorkRequest simples e enfileirá-lo.

Neste guia, você aprenderá a personalizar solicitações de trabalho para lidar com casos de uso comum:

  • Lidar com restrições de tarefas, como disponibilidade de rede
  • Garantir um atraso mínimo na execução de tarefas
  • Gerenciar novas tentativas de tarefas e espera
  • Processar entrada e saída de tarefas
  • Agrupar tarefas com tags

Restrições de trabalho

Você pode adicionar Constraints ao seu trabalho para indicar quando ele pode ser executado.

Por exemplo, você pode especificar que o trabalho só será executado quando o dispositivo estiver inativo e conectado à energia.

O código abaixo mostra como você pode adicionar essas restrições a um OneTimeWorkRequest. Para ver uma lista completa de restrições compatíveis, consulte a documentação de referência do Constraints.Builder.

Kotlin


    // Create a Constraints object that defines when the task should run
    val constraints = Constraints.Builder()
            .setRequiresDeviceIdle(true)
            .setRequiresCharging(true)
            .build()

    // ...then create a OneTimeWorkRequest that uses those constraints
    val compressionWork = OneTimeWorkRequestBuilder<CompressWorker>()
            .setConstraints(constraints)
            .build()

    

Java

    // Create a Constraints object that defines when the task should run
    Constraints constraints = new Constraints.Builder()
        .setRequiresDeviceIdle(true)
        .setRequiresCharging(true)
         .build();

    // ...then create a OneTimeWorkRequest that uses those constraints
    OneTimeWorkRequest compressionWork =
                    new OneTimeWorkRequest.Builder(CompressWorker.class)
         .setConstraints(constraints)
         .build();
    

Quando várias restrições forem especificadas, a tarefa será executada somente quando todas elas forem atendidas.

Caso uma restrição falhe enquanto a tarefa estiver em execução, o WorkManager interromperá o worker. A tarefa será tentada novamente quando as restrições forem atendidas.

Atrasos iniciais

Se seu trabalho não tiver restrições ou se todas as restrições forem atendidas quando o trabalho for enfileirado, o sistema poderá executar a tarefa imediatamente. Se você não quiser que a tarefa seja executada imediatamente, especifique um atraso inicial mínimo depois do qual o trabalho será iniciado.

Veja um exemplo de como configurar sua tarefa para ser executada pelo menos 10 minutos depois de ser enfileirada.

Kotlin


    val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
            .setInitialDelay(10, TimeUnit.MINUTES)
            .build()

    

Java


    OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(UploadWorker.class)
            .setInitialDelay(10, TimeUnit.MINUTES)
            .build();

    

Política de novas tentativas e espera

Se você precisar que o WorkManager tente realizar a tarefa novamente, poderá retornar Result.retry() do worker.

Seu trabalho será reprogramado com uma política e um atraso de espera padrão. O atraso de espera especifica o tempo mínimo que é necessário aguardar antes de tentar realizar novamente o trabalho. A política de espera define como o atraso de espera aumentará ao longo do tempo para as seguintes tentativas de repetição. Ela é EXPONENTIAL por padrão.

Veja um exemplo de personalização do atraso e da política de espera.

Kotlin


    val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
            .setBackoffCriteria(
                    BackoffPolicy.LINEAR,
                    OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                    TimeUnit.MILLISECONDS)
            .build()

    

Java


    OneTimeWorkRequest uploadWorkRequest =
        new OneTimeWorkRequest.Builder(UploadWorker.class)
            .setBackoffCriteria(
                    BackoffPolicy.LINEAR,
                    OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
                    TimeUnit.MILLISECONDS)
            .build();
    

Como definir entrada/saída para sua tarefa

Sua tarefa pode exigir que os dados sejam passados como parâmetros de entrada ou retornados como um resultado. Por exemplo, uma tarefa que gerencia o upload de uma imagem requer que o URI da imagem seja enviado como entrada e pode exigir o URL da imagem enviada como saída.

Os valores de entrada e saída são armazenados como pares de chave-valor em um objeto Data. O código abaixo mostra como definir dados de entrada na sua WorkRequest.

Kotlin


    // workDataOf (part of KTX) converts a list of pairs to a [Data] object.
    val imageData = workDataOf(Constants.KEY_IMAGE_URI to imageUriString)

    val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
            .setInputData(imageData)
            .build()

    

Java


    Data imageData = new Data.Builder()
                    .putString(Constants.KEY_IMAGE_URI, imageUriString)
                    .build();

    OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest.Builder(UploadWorker.class)
            .setInputData(imageData)
            .build();
    

A classe Worker pode acessar os argumentos de entrada chamando Worker.getInputData().

Da mesma forma, a classe Data pode ser usada para gerar um valor de retorno. Retorne o objeto Data incluindo-o no Result de Result.success() ou Result.failure(), conforme mostrado abaixo.

Kotlin

    class UploadWorker(appContext: Context, workerParams: WorkerParameters)
        : Worker(appContext, workerParams) {

        override fun doWork(): Result {

                // Get the input
                val imageUriInput = getInputData().getString(Constants.KEY_IMAGE_URI)
                // TODO: validate inputs.
                // Do the work
                val response = uploadFile(imageUriInput)

                // Create the output of the work
                val outputData = workDataOf(Constants.KEY_IMAGE_URL to response.imageUrl)

                // Return the output
                return Result.success(outputData)

        }
    }

    

Java

    public class UploadWorker extends Worker {

        public UploadWorker(
            @NonNull Context context,
            @NonNull WorkerParameters params) {
            super(context, params);
        }

        @Override
        public Result doWork() {

            // Get the input
            String imageUriInput =
                    getInputData().getString(Constants.KEY_IMAGE_URI);
            // TODO: validate inputs.
            // Do the work
            Response response = uploadFile(imageUriInput);

            // Create the output of the work
            Data outputData = new Data.Builder
                    .putString(Constants.KEY_IMAGE_URL, response.imageUrl)
                    .build();

            // Return the output
            return Result.success(outputData);
        }
    }
    

Trabalho de tag

Você pode agrupar suas tarefas de forma lógica atribuindo uma string de tags a qualquer objeto WorkRequest. Isso permite que você opere em todas as tarefas com uma tag específica.

Por exemplo, WorkManager.cancelAllWorkByTag(String) cancela todas as tarefas com uma tag específica, e WorkManager.getWorkInfosByTagLiveData(String) retorna um LiveData com uma lista de status de todas as tarefas com essa tag.

O código a seguir mostra como adicionar uma tag de "limpeza" à sua tarefa com WorkRequest.Builder.addTag(String):

Kotlin

    val cacheCleanupTask =
            OneTimeWorkRequestBuilder<CacheCleanupWorker>()
        .setConstraints(constraints)
        .addTag("cleanup")
        .build()
    

Java

    OneTimeWorkRequest cacheCleanupTask =
            new OneTimeWorkRequest.Builder(CacheCleanupWorker.class)
        .setConstraints(constraints)
        .addTag("cleanup")
        .build();