Visão geral do trabalho em segundo plano

Com frequência, os apps precisam fazer mais de uma coisa por vez. As APIs do Android oferecem várias maneiras diferentes de fazer isso. Escolher a opção certa é muito importante: uma opção pode ser certa para uma situação, mas muito errada para outra. Escolher as APIs erradas pode prejudicar a performance do app ou a eficiência de recursos, o que pode descarregar a bateria e prejudicar o desempenho do dispositivo do usuário como um todo. Em alguns casos, escolher a abordagem errada pode impedir que seu app seja listado na Play Store.

Este documento explica as diferentes opções disponíveis e ajuda você a escolher a certa para sua situação.

Terminologia

Alguns termos importantes relacionados ao trabalho em segundo plano podem ser usados de várias formas e contraditórias. Por isso, é importante definir nossos termos.

Se um app estiver sendo executado em segundo plano, o sistema aplicará diversas restrições. Por exemplo, na maioria dos casos, um app em segundo plano não pode iniciar serviços em primeiro plano.

Para os fins deste documento, usaremos o termo "tarefa" para significar uma operação que um app está fazendo fora do fluxo de trabalho principal. Para garantir o alinhamento na compreensão, colocamos isso em três categorias principais de tipos de tarefas: trabalho assíncrono, trabalho em segundo plano e serviços em primeiro plano.

Escolha a opção certa

Na maioria dos cenários, você pode descobrir as APIs certas a serem usadas para sua tarefa descobrindo a categoria (trabalho assíncrono, trabalho em segundo plano ou serviços em primeiro plano) em que a tarefa se enquadra.

Se você ainda não tiver certeza, use os fluxogramas fornecidos, que adicionam mais nuances à decisão. Cada uma dessas opções é descrita em mais detalhes posteriormente neste documento.

Há dois cenários principais a serem considerados para o trabalho em segundo plano:

Esses dois cenários têm as próprias árvores de decisão.

Trabalho assíncrono

Em muitos casos, um app só precisa fazer operações simultâneas enquanto estiver sendo executado em primeiro plano. Por exemplo, um app pode precisar fazer um cálculo demorado. Se ele fizesse o cálculo na linha de execução de IU, o usuário não poderia interagir com o app até que o cálculo fosse concluído. Isso pode resultar em um erro de ANR. Nesse caso, o app precisa usar uma opção de trabalho assíncrono.

Opções de trabalho assíncronos comuns incluem corrotinas do Kotlin e linhas de execução Java. Você encontra mais informações na documentação de trabalho assíncrono. É importante observar que, ao contrário do trabalho em segundo plano, não há garantia de que o trabalho assíncrono será concluído se o app parar de estar em um estágio do ciclo de vida válido (por exemplo, se o app sair do primeiro plano).

Trabalho em segundo plano

O trabalho em segundo plano é uma opção mais flexível quando você precisa fazer um trabalho que continuará mesmo se o usuário sair do app. Na maioria dos casos, a melhor opção para trabalhos em segundo plano é usar o WorkManager, embora em alguns casos possa ser adequado usar a API JobScheduler da plataforma.

O WorkManager é uma biblioteca avançada que permite configurar jobs simples ou complicados conforme necessário. Você pode usar o WorkManager para agendar tarefas a serem executadas em horários específicos ou especificar as condições em que a tarefa será executada. Você pode até configurar cadeias de tarefas para que cada tarefa seja executada por vez, transmitindo os resultados para a próxima. Para entender todas as opções disponíveis, leia a lista de recursos do WorkManager.

Alguns dos cenários mais comuns para trabalhos em segundo plano são:

  • Buscar dados do servidor periodicamente
  • Buscando dados do sensor (por exemplo, dados do contador de passos)
  • Receber dados de local periódicos (você precisa ter a permissão ACCESS_BACKGROUND_LOCATION no Android 10 ou versões mais recentes)
  • Fazer upload de conteúdo com base em um acionador de conteúdo, como fotos criadas pela câmera

Serviços em primeiro plano

Os serviços em primeiro plano oferecem uma maneira eficiente de executar imediatamente tarefas que não precisam ser interrompidas. No entanto, os serviços em primeiro plano podem sobrecarregar o dispositivo e, às vezes, têm implicações de privacidade e segurança. Por esses motivos, o sistema impõe muitas restrições sobre como e quando os apps podem usar serviços em primeiro plano. Por exemplo, um serviço em primeiro plano precisa ser perceptível para o usuário e, na maioria dos casos, os apps não podem iniciar serviços em primeiro plano quando estão em segundo plano. Para mais informações, consulte a documentação de serviços em primeiro plano.

Há dois métodos para criar um serviço em primeiro plano. É possível declarar seu próprio Service e especificar que o serviço é em primeiro plano chamando Service.startForeground(). Como alternativa, você pode usar o WorkManager para criar um serviço em primeiro plano, conforme discutido em Suporte a workers de longa duração. No entanto, é importante saber que um serviço em primeiro plano criado pelo WorkManager precisa obedecer às mesmas restrições de qualquer outro serviço desse tipo. O WorkManager apenas fornece algumas APIs de conveniência para simplificar a criação de um serviço em primeiro plano.

APIs alternativas

O sistema oferece APIs alternativas projetadas para ter uma performance melhor em casos de uso mais específicos. Se houver uma API alternativa para seu caso de uso, recomendamos usar essa API em vez de um serviço em primeiro plano, já que isso vai melhorar a performance do app. A documentação dos tipos de serviço em primeiro plano observa quando há uma boa API alternativa para usar em vez de um tipo de serviço em primeiro primeiro plano específico.

Alguns dos cenários mais comuns para usar APIs alternativas são:

Tarefas iniciadas pelo usuário

Fluxograma mostrando como escolher a API adequada. Este gráfico
  resume o material na seção "Tarefas iniciadas pelo usuário".
Figura 1: como escolher a API certa para executar uma tarefa em segundo plano iniciada pelo usuário.

Se um app precisar executar um trabalho em segundo plano e a operação for iniciada pelo usuário enquanto ele estiver visível, responda a estas perguntas para encontrar a abordagem correta.

A tarefa precisa continuar em execução enquanto o app está em segundo plano?

Se a tarefa não precisar continuar funcionando enquanto o app estiver em segundo plano, use um trabalho assíncrono. Há várias opções para realizar trabalhos assíncronos. O importante é entender que essas opções param de funcionar se o app fica em segundo plano. Eles também serão interrompidos se o app for desligado. Por exemplo, um app de mídia social pode querer atualizar o feed de conteúdo, mas não precisa concluir a operação se o usuário saiu da tela.

A tarefa será adiada ou interrompida se a tarefa for adiada ou interrompida?

É importante considerar se a experiência do usuário não será prejudicada se uma tarefa for adiada ou cancelada. Por exemplo, se um app precisa atualizar os recursos, o usuário pode não perceber se a operação acontece imediatamente ou no meio da noite enquanto o dispositivo está recarregando. Nesses casos, é preciso usar as opções de trabalho em segundo plano.

É uma tarefa curta e crítica?

Se a tarefa não puder ser atrasada e for concluída rapidamente, você poderá usar um serviço em primeiro plano com o tipo shortService. Esses serviços são mais fáceis de criar do que outros serviços em primeiro plano e não exigem muitas permissões. No entanto, os serviços curtos precisam ser concluídos em até três minutos.

Existe uma API alternativa apenas para essa finalidade?

Se a tarefa não estiver invisível para o usuário, a solução correta pode ser usar um serviço em primeiro plano. Esses serviços são executados continuamente após iniciados. Por isso, são uma boa opção quando interromper a tarefa resulta em uma experiência do usuário ruim. Por exemplo, um app de monitoramento de treinos pode usar sensores de localização para permitir que os usuários registrem o trajeto da corrida em um mapa. Não convém fazer isso com uma opção de trabalho em segundo plano, porque se a tarefa fosse pausada, o rastreamento pararia imediatamente. Nessa situação, é melhor um serviço em primeiro plano.

No entanto, como os serviços em primeiro plano podem usar muitos recursos do dispositivo, o sistema impõe muitas restrições sobre quando e como eles podem ser usados. Em muitos casos, em vez de usar um serviço em primeiro plano, é possível usar uma API alternativa que executa o job com menos problemas. Por exemplo, se o app precisar realizar uma ação quando o usuário chegar a determinado local, a melhor opção é usar a API geofence em vez de rastrear a localização do usuário com um serviço em primeiro plano.

Tarefas em resposta a um evento

Fluxograma mostrando como escolher a API adequada. Este gráfico
  resume o material na seção "Tarefas em resposta a um evento".
Figura 2: como escolher a API certa para executar uma tarefa em segundo plano acionada por um evento.

Às vezes, um app precisa fazer um trabalho em segundo plano em resposta a um gatilho, como:

Pode ser um gatilho externo, como uma mensagem do FCM, ou pode ser em resposta a um alarme definido pelo próprio app. Por exemplo, um jogo pode receber uma mensagem do FCM solicitando a atualização de alguns recursos.

Se você tiver certeza de que a tarefa será concluída em alguns segundos, use um trabalho assíncrono. O sistema vai permitir que o app execute essas tarefas em alguns segundos, mesmo que ele esteja em segundo plano.

Se a tarefa demorar mais do que alguns segundos, pode ser apropriado iniciar um serviço em primeiro plano para processá-la. Na verdade, mesmo que seu app esteja em segundo plano, pode ser permitido iniciar um serviço em primeiro plano se a tarefa tiver sido acionada pelo usuário e se enquadrar em uma das isenções de restrições de início em segundo plano aprovadas. Por exemplo, se um app recebe uma mensagem de alta prioridade do FCM, ele tem permissão para iniciar um serviço em primeiro plano mesmo se estiver em segundo plano.

Se a tarefa demorar mais do que alguns segundos, use um trabalho em segundo plano.