Estoy diseñando una aplicación que tiene la tarea recurrente de enviar presencia a un servidor dedicado siempre que la aplicación esté en primer plano.
En mis búsquedas en la web, vi algunos enfoques diferentes y quería saber cuál es la mejor manera de hacerlo.
¿Cuál es la mejor forma de programar una llamada al servidor?
Las opciones que vi fueron:
Servicio .
BroadcastReciever con AlarmManager .
¿Cual es tu opinion?
EDITAR:
La razón por la que necesito esto es para una aplicación basada en chat que envía todas las acciones del usuario a un servidor remoto.
es decir, el usuario está escribiendo un mensaje, el usuario está leyendo un mensaje, el usuario está en línea, el usuario está fuera de línea, etc.
Esto significa que una vez en cada intervalo, necesito enviar al servidor lo que estoy haciendo, ya que abro una sala de chat con otras personas, necesitan saber lo que estoy haciendo.
Similar al mecanismo de retroalimentación de mensajes de WhatsApp:
EDICIÓN # 2: las
tareas recurrentes ahora deben programarse casi siempre a través de la JobScheduler
API (o FirebaseJobDispatcher
para API inferiores) para evitar problemas de agotamiento de la batería, como se puede leer en la sección de aspectos vitales de la capacitación de Android
EDICIÓN # 3:
FirebaseJobDispatcher ha quedado obsoleto y reemplazado por Workmanager , que también incorpora funciones de JobScheduler.
fuente
Respuestas:
No estoy seguro, pero según mi conocimiento, comparto mis puntos de vista. Siempre acepto la mejor respuesta si me equivoco.
Administrador de alarmas
El administrador de alarmas mantiene un bloqueo de activación de la CPU mientras se
onReceive()
esté ejecutando el método del receptor de alarma . Esto garantiza que el teléfono no se suspenderá hasta que haya terminado de manejar la transmisión. Una vez queonReceive()
regresa, el administrador de alarmas libera este bloqueo de activación. Esto significa que, en algunos casos, el teléfono se dormirá tan pronto comoonReceive()
se complete el método. Si llamó su receptor de alarmaContext.startService()
, es posible que el teléfono se suspenda antes de que se inicie el servicio solicitado. Para evitar esto, suBroadcastReceiver
yService
deberá implementar una política de bloqueo de activación separada para garantizar que el teléfono continúe funcionando hasta que el servicio esté disponible.Nota: El Administrador de alarmas está diseñado para casos en los que desea que el código de su aplicación se ejecute en un momento específico, incluso si su aplicación no se está ejecutando actualmente. Para las operaciones de cronometraje normales (ticks, tiempos de espera, etc.) es más fácil y mucho más eficiente utilizar Handler.
Temporizador
Timer
tiene algunos inconvenientes que se resuelven medianteScheduledThreadPoolExecutor
. Entonces no es la mejor opciónScheduledThreadPoolExecutor .
Puede usar
java.util.Timer
oScheduledThreadPoolExecutor
(preferido) para programar una acción para que ocurra a intervalos regulares en un hilo en segundo plano.Aquí hay una muestra usando este último:
Así que preferí
ScheduledExecutorService
Pero también piense en que si las actualizaciones ocurrirán mientras su aplicación se está ejecutando, puede usar un
Timer
, como se sugiere en otras respuestas, o el más recienteScheduledThreadPoolExecutor
. Si su aplicación se actualizará incluso cuando no se esté ejecutando, debe utilizar la extensiónAlarmManager
.Tenga en cuenta que si planea actualizar cuando su aplicación está apagada, una vez cada diez minutos es bastante frecuente y, por lo tanto, posiblemente consuma un poco de energía.
fuente
Temporizador
Como se mencionó en los javadocs , es mejor usar un ScheduledThreadPoolExecutor.
ScheduledThreadPoolExecutor
Utilice esta clase cuando su caso de uso requiera varios subprocesos de trabajo y el intervalo de suspensión sea pequeño. Cuán pequeño ? Bueno, yo diría que unos 15 minutos. Los
AlarmManager
intervalos de horario de inicio son en este momento y parece sugerir que para intervalos de sueño más pequeños se puede usar esta clase. No tengo datos para respaldar la última declaración. Es una corazonada.Servicio
Su servicio puede ser cerrado en cualquier momento por la VM. No utilice los servicios para tareas recurrentes. Una tarea recurrente puede iniciar un servicio, que es otro asunto completamente diferente.
BroadcastReciever con AlarmManager
Para intervalos de sueño más largos (> 15 minutos), este es el camino a seguir.
AlarmManager
ya tiene constantes (AlarmManager.INTERVAL_DAY
) que sugieren que puede activar tareas varios días después de que se haya programado inicialmente. También puede activar la CPU para ejecutar su código.Debe utilizar una de esas soluciones en función de sus necesidades de subproceso de trabajo y de tiempo.
fuente
Me doy cuenta de que esta es una pregunta antigua y ha sido respondida, pero esto podría ayudar a alguien. En tus
activity
En
onCreate
fuente
Cotización de la programación de alarmas repetidas: comprender los documentos de compensaciones :
Entonces, en base a esto, la mejor manera de programar una llamada al servidor es utilizando Google Cloud Messaging (GCM) junto con el adaptador de sincronización .
fuente
He creado una tarea a tiempo en la que la tarea que el usuario desea repetir, agrega el método Run () de Custom TimeTask. se está repitiendo con éxito.
}
fuente