0

I've created a non self-terminating intent service by extending IntentService as suggested here: Can an IntentService run indefinitely?

A consequence of this is that if my app crashes my service could still be running the next time I start the MainActivity. Is there a recommended way to determine if an arbitrary service is running?

I've seen solutions recommend I set a flag in the onCreate and onDestroy methods of the service, but a service can end without onDestroy being invoked (for example if it crashes) so that's not a perfect solution.

Community
  • 1
  • 1
Keith Carter
  • 422
  • 1
  • 6
  • 18

1 Answers1

1

One thing to keep in mind is that your Service and your Activity are the same app and the same process - if one crashes they are both gone. There are ways to separate them, but it is not the normal approach and likely not what you want. Even if the Service was still available, it shouldn't matter to your Activity as they communicate with each other via Intent, which is roughly a message between the two.

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
  • Actually, that separation is desired in this case. My activity starts the service but if the activity is gone I still want the service to function. It isn't really relevant for this question, but my service communicates back to the activity using using the LocalBroadcastManager. – Keith Carter Dec 22 '14 at 03:43
  • I should also mention: the only reason I'm curious about this is because I've observed the situation where the Activity crashes but the service is still running. When I create a new Activity and its BroadcastReceivers the receivers are firing. So I know the old service is still running. – Keith Carter Dec 22 '14 at 03:48
  • Unless you have specified in the manifest that the service and activity are to be in different processes, they are always in the same process. What you are likely seeing is the system restarting your app's process because you had a started service running when it crashed. – Larry Schiefer Dec 22 '14 at 03:58
  • What are you really trying to do? – Larry Schiefer Dec 22 '14 at 04:00
  • Thanks for sticking with me here. What I'm trying to do is create an app that tracks a user's location. They start the activity and then press a button to start the service. When the app crashes, I'd like to the activity to show if the service is still running when they start the activity again. – Keith Carter Dec 22 '14 at 16:02
  • To do something like that you'd have to completely decouple them. Though for *normal* operating modes you wouldn't have to. What I mean by *normal* is no crashing. If the user starts the `Activity` and starts getting location (because it started the `Service`) then leaves the `Activity`, the `Service` will have no problems staying present if constructed properly. That's actually the typical usage case. – Larry Schiefer Dec 22 '14 at 17:20
  • How would one completely decouple them? And once they were, how would the activity know if the decoupled service is running? – Keith Carter Dec 22 '14 at 17:27
  • As I mentioned: you shouldn't have to decouple them. Using them doesn't change at the API level for most things. It will if you're going to pass custom objects between them. There should be no need to check if the `Service` is running already. The `Activity` will just `startService()` like normal and begin using it. A `Service` is not a standalone process/daemon (though are often used like one.) – Larry Schiefer Dec 22 '14 at 17:38
  • The reason I need to check if the service is running or not is because at activity start up there is no way to reliably know if the service is running already. I need to know because the service isn't meant to just startService on activity start. The user has the option to turn the service on or off. I can't give them that option if I don't know if the service is running. – Keith Carter Dec 22 '14 at 17:42
  • In this case, you'd probably want to have your `Service` "running" (or not care if it is), but perhaps not in an "active" state. So you add an `Intent` based API (messages) or `Binder` exposed interface where the `Activity` could query/set the current state of the `Service`. – Larry Schiefer Dec 22 '14 at 17:52
  • Once that was done, how would I know if the service was running and more importantly, active? – Keith Carter Dec 22 '14 at 18:50
  • You wouldn't have to know it's running, your `Activity` could just `startService()` with an `Intent` you define for establishing a connection and possibly starting the `Service` for the first time. You could then send an `Intent` to get the current "active" state or perhaps "register" your own `BrodcastReceiver` instance with the `Service` which causes it to go "active". Of course, there are more ways than just this. If you really want your `Service` to stick around longer than `IntentService`, you could instead create a `Binder` based API (even within the same process). – Larry Schiefer Dec 22 '14 at 21:03