El servicio de fondo de Android se está reiniciando cuando se cancela la aplicación

Estoy desarrollando una aplicación en la que se crea un servicio de fondo para recopilar datos de sensores. Estoy comenzando el servicio de mi actividad:

startService(new Intent(this, MyService.class)); 

He creado el servicio así que si la aplicación es destruida, el servicio de fondo sigue recopilando datos. He intentado esto, y funcionó hasta cierto punto. Mi problema es que cuando mato la aplicación, el servicio parece reiniciar porque se onCreate() los onCreate() y onStart() . ¿Hay alguna manera con la que el servicio no se reinicia por favor?

ACTUALIZAR:

Como se sugiere en una respuesta a continuación, he añadido el siguiente método en el servicio, pero no hay suerte.

 @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_NOT_STICKY; } 

Depende del valor devuelto en onStartCommand.

Debe devolver START_NOT_STICKY

Según la documentación :

Para los servicios iniciados, hay dos modos de operación principales adicionales que pueden decidir ejecutar, dependiendo del valor que devuelven desde onStartCommand (): START_STICKY se utiliza para servicios que se inician y detienen explícitamente según sea necesario, mientras que START_NOT_STICKY o START_REDELIVER_INTENT se utilizan Para servicios que sólo deberían seguir ejecutándose mientras se procesan los comandos enviados a ellos

En resumen: si devuelve START_STICKY, el servicio se vuelve a crear siempre que los recursos estén disponibles. Si devuelve START_NOT_STICKY tiene que volver a activar el servicio enviando una nueva intención.

Como todo esto despertó mi curiosidad, hice una aplicación de ejemplo para probar esto. Usted puede encontrar el zip con todas las fuentes aquí Hay un botón startService y un botón stopService que hacen lo que se espera de ellos. El servicio devuelve START_NOT_STICKY en onStartCommand. Puse tostadas en onCreate, onStartCommand y onDestroy.

Aquí lo que sucede:

  • Si presiono start, onCreate y onStart se llaman
  • Si presiono stop, onDestroy se activa
  • Si presiono dos veces iniciar, onCreate se llama una vez y onStartCommand dos veces

Por lo tanto, se comporta como uno esperaría.

Si inicio el servicio y cancelo la aplicación como describí, onDestroy no se llama, pero tampoco onCreate o onStart.

Si regreso a la aplicación y presione iniciar de nuevo, onCreate se llama, lo que significa que, como escribí antes, START_NOT_STICKY impide que el servicio se reinicie automáticamente.

Supongo que tienes algo más en tu aplicación que inicia el servicio de nuevo (tal vez una intención pendiente).

La aplicación y el servicio en vivo en el mismo proceso, lo que significa que cuando se cancela la aplicación por lo que es su servicio. Cambiar el valor devuelto de onStartCommand no afecta a este proceso. Simplemente le dice al Servicio que empiece / pare cuando lo diga o cuando termine de hacer lo que necesita. Como se mencionó en su comentario a su publicación original, establecerlo como un proceso de primer plano funcionó, pero eso es realmente sólo obligar al servicio a tener una alta prioridad, no resolver el problema.

Para cambiar el servicio para que se destruya por separado y asumiendo que es un servicio iniciado en lugar de un servicio enlazado debido al uso de onStartCommand, especifique un nombre de proceso en el manifiesto para ese servicio.

En la Guía para desarrolladores de procesos e hilos :

La entrada de manifiesto para cada tipo de componente elemento – <activity>, <service>, <receiver>, and <provider> – admite un atributo android: proceso que puede especificar un proceso en el que ese componente debe ejecutarse. Puede establecer este atributo para que cada componente se ejecute en su propio proceso o para que algunos componentes compartan un proceso mientras que otros no lo hacen. También puede configurar android: proceso para que los componentes de diferentes aplicaciones se ejecuten en el mismo proceso, siempre que las aplicaciones compartan el mismo ID de usuario de Linux y estén firmadas con los mismos certificados.

Android podría decidir cerrar un proceso en algún momento, cuando la memoria es baja y requerida por otros procesos que son más inmediatos al usuario. Los componentes de la aplicación que se ejecutan en el proceso que se ha matado son destruidos en consecuencia. Se vuelve a iniciar un proceso para esos componentes cuando vuelva a haber trabajo para ellos.

De <service> en el archivo de manifiesto :

Androide: proceso

El nombre del proceso en el que se ejecutará el servicio. Normalmente, todos los componentes de una aplicación se ejecutan en el proceso predeterminado creado para la aplicación. Tiene el mismo nombre que el paquete de aplicación. El atributo de proceso del elemento puede establecer un valor predeterminado diferente para todos los componentes. Sin embargo, el componente puede anular el valor predeterminado con su propio atributo de proceso, lo que le permite extender su aplicación a través de múltiples procesos.

Si el nombre asignado a este atributo comienza con dos puntos (':'), se crea un nuevo proceso, privado para la aplicación, cuando es necesario y el servicio se ejecuta en ese proceso. Si el nombre del proceso comienza con un carácter en minúscula, el servicio se ejecutará en un proceso global de ese nombre, siempre que tenga permiso para hacerlo. Esto permite a los componentes de diferentes aplicaciones compartir un proceso, reduciendo el uso de recursos.

No sé por qué la otra respuesta que mencionó esto fue votado. He utilizado este método en el pasado y, hoy, creado una aplicación de actividad simple con un servicio en un proceso diferente sólo para asegurarse de que no estaba loco. He utilizado el monitor de dispositivos Android para matar el proceso de la aplicación. Puede ver ambos procesos separados en ADM y puede ver que cuando el proceso de la aplicación es eliminado, el servicio no lo es.

Si está utilizando un IntentService, tiene un

 onHandleIntent() 

Método en el que debe colocar el código que debe ejecutarse. Se ejecuta en un hilo independiente (no un subproceso de interfaz de usuario en el que se ejecuta la aplicación), por lo tanto, su aplicación no debería afectarla. Cuando el código ha terminado de ejecutarse, el hilo se termina y el servicio se detiene automáticamente.

Sé que es muy tarde para responder a esta pregunta, pero puede ser que puede ser útil a los demás. Esto realmente me ayudó para mi aplicación de reproductor de música.

Si hay servicios que pueden ser perjudiciales o pueden afectar la experiencia del usuario como la música, etc, entonces en ese caso usted tiene que utilizar la notificación y cuando el servicio se inicia con éxito, a continuación, crear la notificación y utilizar la función

 startForeground(int Notification_id,Notification); 

Esto ejecutará su servicio en segundo plano sin reiniciar y reinvoking sus métodos

https://developer.android.com/reference/android/app/Service.html

El comienzo no pegajoso no trabaja sobre kitkat, y el otro onTaskRemoved no trabajando sobre Marshmellow. OnTaskRemoved podría ser utilizado por manejado algunas excepciones. No funcionó en eso. Pero trate de que uno.

Cuando la memoria es baja, un servicio que se ejecuta en segundo plano se destruye automáticamente. En lugar de usar startService () para iniciar un servicio, pruebe a usar StartForeground (). El servicio se ejecuta en primer plano y nunca se matará, incluso si la memoria es baja.

Me encontré con el mismo problema y fue capaz de resolverlo haciendo que el servicio se ejecute en un proceso global. Para ello, agregue lo siguiente a la etiqueta de manifiesto:

Process = "com.myapp.ProcessName"

(Marca cualquier nombre.)

Cuando lo hice, descubrí que mi servicio no se había eliminado (y reiniciado) cuando se eliminó la aplicación de la lista. Es de suponer que esto se debe a que el proceso de aplicación se elimina cuando lo desliza, pero los procesos de servicio global no lo son.

La desventaja de esto es que la comunicación entre su aplicación y el servicio ahora tiene que ser a través de la interfaz IBinder; No puede llamar directamente a las funciones de la aplicación o del servicio del otro, porque están ejecutándose en distintos procesos.

  • 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?
  • "No se puede realizar esta acción en una instancia no sellada" excepción java.lang.IllegalStateException
  • El punto de interrupción en servicio no funciona
  • ¿Cómo saber cuántas aplicaciones se ejecutan en segundo plano en android?
  • Obtener ubicación GPS a través de un servicio en Android
  • El servicio no se reinicia después de que "Clear Memory" + appWidget se bloquea
  • ¿Es posible utilizar la herencia en las interfaces AIDL?
  • En Android: ¿Cómo llamar a la función de la actividad de un servicio?
  • Servicio de Android que no recibe Actualizaciones de ubicación
  • ¿Cómo iniciar AccessibilityService?
  • Android: superposición en la ventana sobre las actividades de una tarea
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.