I'm starting a service using
startService(new Intent(this, RelayService.class));
and then the service starts an alarm using
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);
and then BroadcastReceiver SyncAlarmReciver
is trying to get the service using
RelayServiceBinder relay = (RelayServiceBinder)
peekService(context, new Intent(context, RelayService.class));
It all works fine until the service is restarted by the system after application gets killed when other applications need more memory. After restart, the service relaunches the alarm using the same code, but peekService()
returns null. Through debugging messages, I see that context
in the service and in the broadcast receiver is the same, as well as RelayService object, i.e. these objects are the same objects in memory. How can I solve this problem?
If it helps, here are links to the three pieces of the code mentioned: main activity, service, broadcast receiver.
P.S. I know that the service is running continuosly because I'm watching the process closely and see it running fine and not restarting in any way, and also because I see that connection it opens before launching the alarm does not get interrupted.
As suggested by JesusFreke, the problem is that
peekService()
can only return an existingIBinder
object. As the service is restarted by the system and there's noActivity
that would bind to the service at this point, theIBinder
object does not exist yet. So anull
is returned. It's a shame that documentation misses this fact entirely.As I definitely didn't want to start the service if it wasn't running, using
startService()
seemed a bad idea, so I resorted to quering a static attribute of the service (which was there anyway).