peekService() returns null even though the service is running, if the service is restarted by the system after OOM kill

杀马特。学长 韩版系。学妹 提交于 2019-12-07 08:20:28

问题


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:


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).



来源:https://stackoverflow.com/questions/27391858/peekservice-returns-null-even-though-the-service-is-running-if-the-service-is

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!