peekService() returns null even though the service

2019-05-04 15:56发布

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.

1条回答
劳资没心,怎么记你
2楼-- · 2019-05-04 16:33

As suggested by JesusFreke, the problem is that peekService() can only return an existing IBinder object. As the service is restarted by the system and there's no Activity that would bind to the service at this point, the IBinder object does not exist yet. So a null 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).

查看更多
登录 后发表回答