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

Linhas de execução no Worker

Quando você usa um Worker, o WorkManager chama Worker.doWork() automaticamente em uma linha de execução de segundo plano. A linha de execução em segundo plano vem do Executor especificado na Configuration do WorkManager. Por padrão, o WorkManager configura um Executor, mas também é possível personalizar o seu. Por exemplo, você pode compartilhar um Executor de segundo plano existente no app ou criar um Executor de linha de execução única para garantir que todo o trabalho em segundo plano seja executado em série ou até mesmo especificar um ThreadPool com uma contagem de linha de execução diferente. Para personalizar o Executor, ative a inicialização manual do WorkManager. Ao configurar o WorkManager, você pode especificar o Executor da seguinte maneira:

Kotlin

    WorkManager.initialize(
        context,
        Configuration.Builder()
            .setExecutor(Executors.newFixedThreadPool(8))
            .build())
    

Java

    WorkManager.initialize(
        context,
        new Configuration.Builder()
            .setExecutor(Executors.newFixedThreadPool(8))
            .build());
    

Veja um exemplo de um Worker simples que faz o download do conteúdo de alguns sites de forma sequencial:

Kotlin

    class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

        override fun doWork(): ListenableWorker.Result {
            for (i in 0..99) {
                try {
                    downloadSynchronously("https://www.google.com")
                } catch (e: IOException) {
                    return ListenableWorker.Result.failure()
                }
            }

            return ListenableWorker.Result.success()
        }
    }
    

Java

    public class DownloadWorker extends Worker {

        public DownloadWorker(Context context, WorkerParameters params) {
            super(context, params);
        }

        @NonNull
        @Override
        public Result doWork() {
            for (int i = 0; i < 100; ++i) {
                try {
                    downloadSynchronously("https://www.google.com");
                } catch (IOException e) {
                    return Result.failure();
                }
            }

            return Result.success();
        }

    }

    

Observe que Worker.doWork() é uma chamada síncrona. Espera-se que você faça todo o trabalho em segundo plano de maneira bloqueada e termine no momento em que o método for encerrado. Se você chamar uma API assíncrona no doWork() e retornar um Result, seu callback poderá não funcionar corretamente. Se você estiver nessa situação, use um ListenableWorker (consulte Linhas de execução no ListableWorker).

Quando um Worker em execução é interrompido por qualquer motivo, ele recebe uma chamada para Worker.onStopped(). Modifique esse método ou chame Worker.isStopped() para verificar seu código e liberar recursos quando necessário. Quando o Worker do exemplo acima for interrompido, ele poderá estar no meio do loop de download de itens e continuará fazendo isso. Para otimizar esse comportamento, você pode fazer algo parecido com o seguinte:

Kotlin

    class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

        override fun doWork(): ListenableWorker.Result {
            for (i in 0..99) {
                if (isStopped) {
                    break
                }

                try {
                    downloadSynchronously("https://www.google.com")
                } catch (e: IOException) {
                    return ListenableWorker.Result.failure()
                }

            }

            return ListenableWorker.Result.success()
        }
    }
    

Java

    public class DownloadWorker extends Worker {

        public DownloadWorker(Context context, WorkerParameters params) {
            super(context, params);
        }

        @NonNull
        @Override
        public Result doWork() {
            for (int i = 0; i < 100; ++i) {
                if (isStopped()) {
                    break;
                }

                try {
                    downloadSynchronously("https://www.google.com");
                } catch (IOException e) {
                    return Result.failure();
                }
            }

            return Result.success();
        }
    }
    

Depois que um Worker for interrompido, independentemente do que Worker.doWork() retornar, o Result será ignorado.