PeekService () devuelve null aunque el servicio se está ejecutando, si el servicio es reiniciado por el sistema después de matar OOM

Empiezo un servicio usando

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

Y luego el servicio inicia una alarma utilizando

 AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, SyncAlarmReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + SYNC_EVERY_MS, SYNC_EVERY_MS, pi); 

Y luego BroadcastReceiver SyncAlarmReciver está intentando obtener el servicio usando

 RelayServiceBinder relay = (RelayServiceBinder) peekService(context, new Intent(context, RelayService.class)); 

Todo funciona bien hasta que el servicio es reiniciado por el sistema después de que la aplicación se mata cuando otras aplicaciones necesitan más memoria. Después de reiniciar, el servicio relanza la alarma utilizando el mismo código, pero peekService() devuelve null. A través de mensajes de depuración, veo que el context en el servicio y en el receptor de difusión es el mismo, así como el objeto RelayService, es decir, estos objetos son los mismos objetos en la memoria. ¿Como puedó resolver esté problema?

Si ayuda, aquí están los enlaces a las tres piezas del código mencionado: actividad principal , servicio , receptor de difusión .

PS Sé que el servicio se está ejecutando continuamente porque estoy viendo el proceso de cerca y ver que funciona bien y no reiniciar de ninguna manera, y también porque veo que la conexión se abre antes de lanzar la alarma no se interrumpe.

Como sugiere JesúsFreke, el problema es que peekService() sólo puede devolver un objeto IBinder existente . A medida que el servicio es reiniciado por el sistema y no hay ninguna Activity que IBinder al servicio en este momento, el objeto IBinder no existe aún. Así que se devuelve un null . Es una pena que la documentación pierda este hecho completamente.

Como definitivamente no quería iniciar el servicio si no estaba funcionando, usar startService() pareció una mala idea, así que recurrí a consultar un atributo estático del servicio (que estaba allí de todos modos).

  • Aplicación de Android como servicio sin actividad
  • ¿Cómo ejecutar el servicio no en el hilo principal?
  • Servicio enlazado a BroadcastReceiver
  • Obtener el color de píxel en segundo plano en Android
  • Obtención de I / art: Explicit concurrent mark sweep GC liberado
  • Cómo supervisar el cambio de estado de SIM
  • ¿Por qué no Service.onStop método?
  • ¿Cómo puedo compartir un servicio entre actividades sin que se reinicie?
  • Android Chronometer, retener el estado de tiempo (y seguir contando en segundo plano)
  • Android: escucha los mensajes SMS entrantes
  • Cómo el calendario de Google o Instagram hacer sus aplicaciones todo el tiempo en marcha y funcionando incluso después de la parada de fuerza
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.