El mejor enfoque para ejecutar el servicio en Android

Tengo un servicio que tiene un tiempo de vida variable. Puede ejecutarse desde 5 minutos hasta 2 horas (por ejemplo). Así que estoy buscando el mejor enfoque para hacer eso, y mi servicio debe lograr las siguientes características:

  • Envíe (a mi servidor) lat-long cada 5 segundos y alguna información adicional ( string , boolean e int )

He intentado un servicio "normal" y he intentado hacer algo como esto para lograr esto:

 public class MyFiveSecondsService extends Service { private Handler handler; Runnable r = new Runnable() { @Override public void run() { //here send my new data } }; public void onCreate(){ super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(handler == null){ handler = new Handler(); } handler.post(r); return super.onStartCommand(intent, flags, startId); } } 

En realidad ese código funciona, pero tengo algunos problemas de rendimiento con ese enfoque, así que traté de hacer algo como esto:

 public class SendUniquePositionIntentService extends IntentService { public SendUniquePositionIntentService() { super("co.bomboapp.Service.IntentService.SendUniquePositionIntentService"); } @Override public void onCreate() { super.onCreate(); } @Override protected void onHandleIntent(Intent intent) { //do the logic here } } public class MyFiveSecondsService extends Service { private Handler handler; Runnable r = new Runnable() { @Override public void run() { //call my SendUniquePositionIntentService here } }; public void onCreate(){ super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(handler == null){ handler = new Handler(); } handler.post(r); return super.onStartCommand(intent, flags, startId); } } 

Y ese enfoque no ha funcionado, cuando había cerrado la aplicación de cualquier servicio sigue funcionando. Así que antes de comenzar cualquier otro intento de lograr esto, quiero alguna dirección, ¿cuál es el mejor enfoque para hacer este "servicio de bucle infinito" y mantener el rendimiento?

Estoy utilizando Android 4.1 como API min y API orientación 5.0. Mi dispositivo de prueba es un Nexus 5 con Android 6. Ahora mismo estoy usando parse.com como base de datos.

"He intentado un servicio" normal "… pero tengo algunos problemas de rendimiento"

De forma predeterminada, un servicio se ejecuta en el subproceso principal de la aplicación, por lo que al crear un controlador con

 public int onStartCommand(Intent intent, int flags, int startId) { if(handler == null){ handler = new Handler(); } ... } 

El controlador se asocia con Looper del subproceso principal y todos los mensajes y ejecutables se entregan y posteriormente se ejecutan en el subproceso. Esa es la razón de los "problemas de rendimiento" . De la documentación :

Recuerde que si utiliza un servicio, todavía se ejecuta en el subproceso principal de su aplicación por defecto …

Respecto al segundo enfoque y la parte

"… cuando yo había cerrado la aplicación de cualquier servicio sigue funcionando"

Usted no ha mencionado cómo exactamente "cerrar" la aplicación, pero lo que puedo ver es

 public int onStartCommand(Intent intent, int flags, int startId) { ... return super.onStartCommand(intent, flags, startId); } 

Lo que significa que si el sistema mata el servicio, de forma predeterminada, se volverá a crear. Así que si "cerrar" su aplicación significa matarla, se llevará a cabo la siguiente cadena de acciones:

  1. El sistema recrea MyFiveSecondsService ,
  2. onStartCommand() es llamado y el manejador publica el runnable
  3. Dentro del método run() SendUniquePositionIntentService se inicia

De la documentación de onStartCommand() :

La implementación predeterminada llama aStart (Intent, int) y devuelve START_STICKY o START_STICKY_COMPATIBILITY.

Tenga en cuenta que iniciar un servicio desde otro (como iniciar SendUniquePositionIntentService de MyFiveSecondsService en su caso) es redundante, a menos que lo intentara.

La parte final de su pregunta es confusa para mí. Por un lado, no funciona para usted porque "… cualquier servicio se mantuvo en funcionamiento" , pero, por otro lado, le gustaría "hacer esto" servicio de bucle infinito " …?

Si sólo necesitas enviar esta información como "strings, booleans e ints" a un servidor (sin ningún comentario al componente que inició el servicio), supongo que es suficiente para que uses IntentService . Este es un marco "out-of-box" que hace su trabajo en un hilo de fondo (lo que le permite evitar la congelación del hilo principal) y se detiene una vez que se hace. Como ejemplo, puede utilizar la documentación de IntentService – está bien escrito.

También tenga en cuenta que el comportamiento de un servicio después de matarlo por el sistema depende del indicador devuelto por onStartCommand() . Por ejemplo, utilice START_NOT_STICKY para no volver a crear el servicio después de matar la aplicación o START_REDELIVER_INTENT para volver a START_REDELIVER_INTENT con la última Intent entregada nuevamente.

  • Eventos de apagado en Android
  • Iniciar servicio desde la notificación
  • IOS equivalente al servicio de Android?
  • Descubrimiento del servicio de red error de tutorial android: Servicio perdido, el teléfono se desactiva
  • Cómo reiniciar el servicio después de que la aplicación sea eliminada de las tareas recientes
  • ¿Cómo reiniciar automáticamente un servicio incluso si la fuerza del usuario lo cierra?
  • El servicio de fondo de Android se está reiniciando cuando se cancela la aplicación
  • Ejecutar servicio incluso si la aplicación está cerrada (matado)
  • Animar ImageView dentro de WindowManager en un servicio de Android
  • Android: superposición en la ventana sobre las actividades de una tarea
  • La notificación de la barra de estado de Android lanza una nueva aplicación aunque esté en ejecución. ¿Cómo sincronizar la aplicación de lanzamiento desde el icono de la aplicación y la notificación de barra de estado?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.