Android: mantener vivo un servicio de fondo (prevenir la muerte del proceso)

Tengo un servicio que se define como:

public class SleepAccelerometerService extends Service implements SensorEventListener 

Esencialmente, estoy haciendo una aplicación que supervisa la actividad del acelerómetro por varias razones, mientras que el usuario duerme con su teléfono o dispositivo en la cama. Este es un servicio de larga duración que NO DEBE ser matado durante la noche. Dependiendo de cuántas aplicaciones de fondo y procesos periódicos ocurren durante la noche, el android a veces mata a mi proceso, terminando así mi servicio. Ejemplo:

 10-04 03:27:41.673: INFO/ActivityManager(1269): Process com.androsz.electricsleep (pid 16223) has died. 10-04 03:27:41.681: INFO/WindowManager(1269): WIN DEATH: Window{45509f98 com.androsz.electricsleep/com.androsz.electricsleep.ui.SleepActivity paused=false} 

No quiero obligar al usuario a tener 'SleepActivity' o alguna otra actividad en mi aplicación como primer plano. No puedo tener mi servicio ejecutado periódicamente, porque está constantemente interceptando onSensorChanged.

¿Algun consejo? Código fuente está aquí: http://code.google.com/p/electricsleep/

7 Solutions collect form web for “Android: mantener vivo un servicio de fondo (prevenir la muerte del proceso)”

Para Android 2.0 o posterior, puede utilizar el método startForeground() para iniciar su servicio en primer plano.

La documentación dice lo siguiente :

Un servicio iniciado puede utilizar la startForeground(int, Notification) para poner el servicio en un estado de primer plano, donde el sistema considera que es algo que el usuario está consciente y por lo tanto no es un candidato para matar cuando la memoria es baja. (Todavía es teóricamente posible que el servicio sea asesinado bajo la presión de la memoria extrema de la aplicación de primer plano actual, pero en la práctica esto no debería ser una preocupación.)

La intención principal es que al matar el servicio podría perturbar al usuario, por ejemplo, matar a un servicio de reproductor de música detendría la reproducción de música.

Deberá proporcionar una Notification al método que se muestra en la barra de notificaciones de la sección En curso.

Cuando enlaza su servicio a la actividad con BIND_AUTO_CREATE, su servicio se está matando justo después de que su actividad se destruye y se desvincula. No depende de cómo haya implementado el método Services unBind, pero aún así será eliminado.

La otra forma es iniciar el servicio con el método startService de su actividad. De esta manera, incluso si su actividad se destruye, su servicio no se destruirá ni siquiera se detendrá, pero tendrá que detenerse / destruirlo por sí mismo con stopSelf / stopService cuando sea apropiado.

Como Dave ya señaló , usted podría ejecutar su Service con prioridad en primer plano. Pero esta práctica sólo debe utilizarse cuando es absolutamente necesario, es decir, cuando podría causar una mala experiencia de usuario si el servicio fue asesinado por Android. Esto es lo que realmente significa el "primer plano": Su aplicación está de alguna manera en primer plano y el usuario se daría cuenta inmediatamente si se ha matado (por ejemplo, porque reprodujo una canción o un video).

En la mayoría de los casos, solicitar prioridad en primer plano para su servicio es contraproducente!

¿Porqué es eso? Cuando Android decide matar a un Service , lo hace porque es corto de recursos (generalmente RAM). Base en las diferentes clases de prioridad, Android decide qué procesos en ejecución, y esto incluye los servicios, para terminar con el fin de liberar recursos. Este es un proceso saludable que quieres que suceda para que el usuario tenga una experiencia fluida. Si solicita la prioridad en primer plano, sin una buena razón, sólo para evitar que su servicio sea asesinado, lo más probable es que cause una mala experiencia de usuario. ¿O puede garantizar que su servicio permanece dentro de un consumo mínimo de recursos y no tiene pérdidas de memoria? 1

Android proporciona servicios pegajosos para marcar los servicios que deben reiniciarse después de un período de gracia si se les mató. Este reinicio normalmente ocurre en unos pocos segundos.

Imagen que desea escribir un cliente XMPP para Android. ¿Debería solicitar prioridad en primer plano para el Service que contiene su conexión XMPP? Definitivamente no, no hay absolutamente ninguna razón para hacerlo. Pero desea usar START_STICKY como indicador de devolución para el método onStartCommand su servicio. Así que su servicio se detiene cuando hay presión de recursos y se reinicia una vez que la situación ha vuelto a la normalidad.

1 : Estoy bastante seguro de que muchas aplicaciones de Android tienen fugas de memoria. Es algo que el programador casual (de escritorio) no le importa mucho.

Tuve un problema similar. En algunos dispositivos después de un tiempo Android mata mi servicio e incluso startForeground () no ayuda. Y a mi cliente no le gusta este problema. Mi solución es utilizar la clase AlarmManager para asegurarse de que el servicio se está ejecutando cuando es necesario. Utilizo AlarmManager para crear una especie de temporizador de vigilancia. Comprueba de vez en cuando si el servicio debe estar funcionando y lo recomienza. También uso SharedPreferences para mantener el indicador si el servicio debe estar funcionando.

Creación / cancelación de mi temporizador de vigilancia:

 void setServiceWatchdogTimer(boolean set, int timeout) { Intent intent; PendingIntent alarmIntent; intent = new Intent(); // forms and creates appropriate Intent and pass it to AlarmManager intent.setAction(ACTION_WATCHDOG_OF_SERVICE); intent.setClass(this, WatchDogServiceReceiver.class); alarmIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager am=(AlarmManager)getSystemService(Context.ALARM_SERVICE); if(set) am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, alarmIntent); else am.cancel(alarmIntent); } 

Recepción y procesamiento de la intención del temporizador de vigilancia:

 /** this class processes the intent and * checks whether the service should be running */ public static class WatchDogServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(ACTION_WATCHDOG_OF_SERVICE)) { // check your flag and // restart your service if it's necessary setServiceWatchdogTimer(true, 60000*5); // restart the watchdogtimer } } } 

De hecho, yo uso WakefulBroadcastReceiver en lugar de BroadcastReceiver . Te di el código con BroadcastReceiver sólo para simplificarlo.

http://developer.android.com/reference/android/content/Context.html#BIND_ABOVE_CLIENT

Public static final int BIND_ABOVE_CLIENT – Añadido en el nivel API 14

Indicador de bindService(Intent, ServiceConnection, int) : indica que la aplicación cliente vinculante a este servicio considera que el servicio es más importante que la propia aplicación. Cuando se establece, la plataforma tratará de tener el asesino de memoria de perder la aplicación antes de que mata el servicio está obligado a, aunque esto no está garantizado que sea el caso.

Otros indicadores del mismo grupo son: BIND_ADJUST_WITH_ACTIVITY, BIND_AUTO_CREATE, BIND_IMPORTANT, BIND_NOT_FOREGROUND, BIND_WAIVE_PRIORITY.

Tenga en cuenta que el significado de BIND_AUTO_CREATE ha cambiado en ICS y las aplicaciones antiguas que no especifican BIND_AUTO_CREATE tendrán automáticamente los indicadores BIND_WAIVE_PRIORITY y BIND_ADJUST_WITH_ACTIVITY establecidos para ellos.

Mantenga su huella de servicio pequeña, esto reduce la probabilidad de que Android cierre su aplicación. No se puede evitar que sea asesinado porque si pudiera, la gente podría fácilmente crear spyware persistente

Estoy trabajando en una aplicación y enfrentar la cuestión de matar a mi servicio en la aplicación de matar. Investigué en google y encontré que tengo que hacerlo en primer plano. Siguiente es el código:

 public class UpdateLocationAndPrayerTimes extends Service { Context context; @Override public void onCreate() { super.onCreate(); context = this; } @Override public int onStartCommand(Intent intent, int flags, int startId) { StartForground(); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } private void StartForground() { LocationChangeDetector locationChangeDetector = new LocationChangeDetector(context); locationChangeDetector.getLatAndLong(); Notification notification = new NotificationCompat.Builder(this) .setOngoing(false) .setSmallIcon(android.R.color.transparent) //.setSmallIcon(R.drawable.picture) .build(); startForeground(101, notification); } } 

Saltos que puede ayudar !!!!

  • Mi BroadcastReceiver no está recibiendo la intención BOOT_COMPLETED después de mis botas N1
  • Cómo detener la repetición de servicios de alarma en Android?
  • Servicio de Android en la biblioteca
  • Android: pasa el objeto de la actividad al servicio
  • Cómo grabar vídeo desde el fondo de la aplicación: Android
  • Android RemoteExceptions and Services
  • Servicio externo de Android desde una biblioteca (AAR, no Shared Service)
  • Background Servicio con Firebase childeventlistener no funciona después de unos minutos
  • ¿Sigue funcionando un servicio incluso cuando el teléfono está dormido?
  • Android: No se pudo importar la clase java.util.ArrayList en el archivo aidl
  • Pasar parámetros a GcmTaskService
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.