O que é o WorkManager?
No Google IO 2018 foi liberado o Android Jetpack, um conjunto de bibliotecas, ferramentas e orientações arquiteturais para ajudar, tornar rápido e facilitar a criação de aplicativos para Android.
O WorkManger está incluído no Jetpack, mas o que é o WorkManager? É uma API que facilita a especificação de tarefas assíncronas, levando em consideração a periodicidade e as condições em que as tarefas serão executadas. Usando um conjunto de APIs, que falarei abaixo, podemos criar uma tarefa e entregá-la ao WorkManager para execução imediata ou no momento apropriado.

Por exemplo, imagine que nosso aplicativo tenha que fazer o download de um podcast semanalmente. Usando essas classes, você pode configurar esta tarefa, escolher as circunstâncias apropriadas para execução (como “somente enquanto o dispositivo estiver conectado à internet”) e entregá-la ao WorkManager para ser executada quando as condições forem atendidas. Sua tarefa está garantida para ser executada, mesmo se o aplicativo for forçado a sair ou o dispositivo for reinicializado.
O WorkManager consegue escolher qual a melhor forma de executar as tarefas baseadas no estado do aplicativo e no nível da API utilizada. Se ele executar uma tarefa enquanto o aplicativo estiver em execução, poderá fazer isto em uma nova thread no processo do seu aplicativo. Se o aplicativo não estiver em execução, ele vai escolher uma maneira apropriada de agendar a tarefa em segundo plano, levando em consideração o nível da API do dispositivo e das dependências incluídas; neste caso, ele poderá usar JobScheduler, Firebase Job Dispatcher ou AlarmManager.
Agora, vamos ver um pouco do que podemos fazer!

Como usar o WorkManager?
Vamos lá, primeiramente devemos adicionar o WorkManager em nosso aplicativo. Para isto, devemos adicionar no arquivo “build.gradle” da aplicação as seguintes linhas abaixo:
dependencies {
def work_version = "1.0.0-alpha01"
implementation "android.arch.work:work-runtime:$work_version"
implementation "android.arch.work:work-firebase:$work_version"
}
O nosso segundo passo é criar o nosso Worker e implementar o método doWork, onde faremos a tarefa. O método doWork retorna um WorkerResult e podemos ter três retornos:
- FAILURE: em caso de falha ou de não conformidades.
- RETRY: significa que houve um erro transitório, ou seja, se o dispositivo perdeu a conexão de rede no meio, então teremos que tentar novamente depois de algum tempo.
- SUCCESS: quando a execução for completada com sucesso.
Logo abaixo, temos um exemplo no qual usamos uma url passada como parâmetro e requisitamos um download ao DownloadManager:
public class DownloadWorker extends Worker {
@NonNull
@Override
public WorkerResult doWork() {
String url = getInputData().getString("key_url", "");
if (URLUtil.isValidUrl(url)) {
long downloadId = downloadFile(url);
Data outputData = new Data.Builder()
.putLong("key_download_id", downloadId).build();
setOutputData(outputData);
return WorkerResult.SUCCESS;
} else {
return WorkerResult.FAILURE;
}
}
public long downloadFile(String url) {
Long result = -1L;
DownloadManager downloadManager = (DownloadManager)
getApplicationContext()
.getSystemService(Context.DOWNLOAD_SERVICE);
if (downloadManager != null) {
DownloadManager.Request request =
new DownloadManager.Request(Uri.parse(url));
result = downloadManager.enqueue(request);
}
return result;
}
}
Como podemos ver acima, podemos adicionar dados ao retorno do método doWork através do método setOutputData passando um Data como parâmetro.
Por fim, vamos agendar a nossa tarefa, mas antes, deixa eu te mostrar alguns Componentes importantes para fazer isso. Primeiro, temos dois tipos de WorkRequest implementados: OneTimeWorkRequest e PeriodicWorkRequest.
- OneTimeWorkRequest: uma classe que representa uma solicitação para trabalho não repetitivo. Exemplo: fazer o upload de uma foto ao clicar no botão.
- PeriodicWorkRequest: uma classe que representa uma solicitação para trabalhos que tem uma repetição. Exemplo: baixar o podcast toda semana sem que o usuário use o aplicativo.
Logo abaixo temos um exemplo no qual estamos agendando um download ao entrar na activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
...
Data inputData = new Data.Builder()
.putString("key_url",
"http://www.awitness.org/prophecy.zip")
.build();
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
OneTimeWorkRequest otwRequest =
new OneTimeWorkRequest.Builder(DownloadWorker.class)
.setInputData(inputData)
.setConstraints(constraints).build();
WorkManager.getInstance().enqueue(otwRequest);
}
E uma das coisas mais legais é que você pode adicionar Constraints para que a sua task seja executada apenas quando satisfazer essas condições. No exemplo acima, o DownloadWorker será executado apenas quando o device estiver conectado à internet.
Outra coisa legal, é que podemos ficar observando a mudança de estados da nossa tarefa e tomar alguma decisão baseado neles:
LiveData<WorkStatus> status =
WorkManager.getInstance().getStatusById(otwRequest.getId());
status.observe(this, new Observer<WorkStatus>() {
@Override
public void onChanged(@Nullable WorkStatus workStatus) {
if (workStatus != null && workStatus.getState().isFinished()) {
//TODO: Faca algo;
}
}
});
Gostaria de agradecer ao Rodrigo Perazzo por me encorajar a escrever e revisar meu artigo!



