Estou projetando um aplicativo que tem uma tarefa recorrente de enviar presença para um servidor dedicado, desde que o aplicativo esteja em primeiro plano.
Nas minhas pesquisas na web, vi algumas abordagens diferentes e queria saber qual é a melhor maneira de fazer isso.
Qual é a melhor maneira de agendar uma chamada de servidor?
As opções que vi foram:
Serviço .
BroadcastReciever com AlarmManager .
Qual a sua opinião?
EDIT:
A razão pela qual eu preciso disso é para um aplicativo baseado em bate-papo que envia todas as ações do usuário para um servidor remoto.
ou seja, o usuário está digitando uma mensagem, o usuário está lendo uma mensagem, o usuário está online, o usuário está offline etc.
Isso significa que, a cada intervalo, preciso enviar ao servidor o que estou fazendo, já que abro uma sala de bate-papo com outras pessoas, elas precisam saber o que estou fazendo.
Semelhante ao mecanismo de feedback da mensagem do whatsapp:
EDIÇÃO 2:
Agora, as tarefas recorrentes devem ser agendadas quase sempre por meio da JobScheduler
API (ou FirebaseJobDispatcher
APIs mais baixas), a fim de evitar problemas de esgotamento da bateria, conforme pode ser lido na seção vitais do treinamento do Android
EDIT # 3: O
FirebaseJobDispatcher foi preterido e substituído pelo Workmanager , que também incorpora recursos do JobScheduler.
fonte
Respostas:
Não tenho certeza, mas de acordo com meu conhecimento, compartilho minhas opiniões. Eu sempre aceito a melhor resposta se estiver errado.
Gerenciador de Alarmes
O Gerenciador de alarmes mantém um bloqueio de ativação da CPU enquanto o
onReceive()
método do receptor de alarme estiver em execução. Isso garante que o telefone não durma até que você termine de lidar com a transmissão. Uma vezonReceive()
retornado, o Gerenciador de alarmes libera esse bloqueio de ativação. Isso significa que, em alguns casos, o telefone irá dormir assim que oonReceive()
método for concluído. Se o seu receptor de alarmeContext.startService()
ligar, é possível que o telefone entre em suspensão antes do lançamento do serviço solicitado. Para evitar isso, o seuBroadcastReceiver
eService
precisará implementar uma política de bloqueio esteira separada para garantir que o telefone continua a funcionar até que o serviço se torna disponível.Nota: O Gerenciador de alarmes destina-se aos casos em que você deseja que o código do seu aplicativo seja executado em um horário específico, mesmo que seu aplicativo não esteja sendo executado no momento. Para operações normais de temporização (ticks, timeouts, etc), é mais fácil e muito mais eficiente usar o Handler.
Cronômetro
Timer
tem algumas desvantagens que são resolvidas porScheduledThreadPoolExecutor
. Portanto, não é a melhor escolhaScheduledThreadPoolExecutor .
Você pode usar
java.util.Timer
ouScheduledThreadPoolExecutor
(preferencial) para agendar uma ação para ocorrer em intervalos regulares em um encadeamento em segundo plano.Aqui está uma amostra usando o último:
Então eu preferi
ScheduledExecutorService
Mas pense também que, se as atualizações ocorrerem enquanto o aplicativo estiver em execução, você poderá usar um
Timer
, como sugerido em outras respostas, ou mais recenteScheduledThreadPoolExecutor
. Se o seu aplicativo for atualizado mesmo quando não estiver em execução, você deverá usar oAlarmManager
.Observe que, se você planeja atualizar quando o aplicativo é desligado, uma vez a cada dez minutos é bastante frequente e, portanto, pode consumir muita energia.
fonte
Cronômetro
Conforme mencionado nos javadocs, é melhor usar um ScheduledThreadPoolExecutor.
ScheduledThreadPoolExecutor
Use esta classe quando seu caso de uso exigir vários encadeamentos de trabalho e o intervalo de suspensão for pequeno. Quão pequeno ? Bem, eu diria cerca de 15 minutos. Os
AlarmManager
horários de início dos intervalos neste momento e parece sugerir que, para intervalos menores de sono, essa classe possa ser usada. Não tenho dados para apoiar a última declaração. É um palpite.Serviço
Seu serviço pode ser fechado a qualquer momento pela VM. Não use serviços para tarefas recorrentes. Uma tarefa recorrente pode iniciar um serviço, o que é outra questão completamente.
BroadcastReciever com AlarmManager
Para intervalos de sono mais longos (> 15 minutos), este é o caminho a percorrer.
AlarmManager
já possui constantes (AlarmManager.INTERVAL_DAY
), sugerindo que ele pode disparar tarefas vários dias após o agendamento inicial. Também pode ativar a CPU para executar seu código.Você deve usar uma dessas soluções com base em suas necessidades de tempo e segmento de trabalho.
fonte
Sei que essa é uma pergunta antiga e foi respondida, mas isso pode ajudar alguém. Na tua
activity
No
onCreate
fonte
Citando os alarmes repetidos de agendamento - Compreenda os documentos de trade-offs :
Portanto, com base nisso, a melhor maneira de agendar uma chamada de servidor é usar o Google Cloud Messaging (GCM) em conjunto com o adaptador de sincronização .
fonte
Eu criei uma tarefa pontual na qual a tarefa que o usuário deseja repetir, adicione o método run () personalizado do TimeTask. está ocorrendo com êxito.
}
fonte