The moose likes Android and the fly likes Service being destroyed? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Mobile » Android
Bookmark "Service being destroyed?" Watch "Service being destroyed?" New topic

Service being destroyed?

Sean Michael Hayes
Ranch Hand

Joined: Feb 08, 2012
Posts: 54

I have an App that is listening on a certain port for messages to come through. I need this service to run as long as the Application is running on the phone. However, the problem I seem to have is that the Service seems to die seconds after it is created in the code and then started again according to the logs and then seems to die again later.

What is weird is that the destruction of the Service is not logged despite me putting a log message in the OnDestroy() method to inform me if it dies.

here is the Service being launched in my main code.

And here is the service, I am using the setForeground method as that seems to be the solution according to Google
Steve Luke

Joined: Jan 28, 2003
Posts: 4181

You should temper the use of setForeground(): it really is used for cases when the user should be aware of the service, and actively cares about it. The setForeground() method itself is badly depricated: it isn't even in newer API levels so if you use it then the app might not work on newer devices. See this for the alternative and a painful method of supporting bot the old and new APIs.

I think the real fix for you is to bind to the server in the application. A service that is bound to an application is not likely to be restarted, and since you seem to indicate the life of the service should be dependent on the life of the application, I think the idea of binding to the service matches the requirement. The IBinder you create will also gives you a channel to communicate with the application or activities (as I am sure is necessary, since you have incoming messages...).

Since you want the service to live as long as the application, and not an activity, you should do the binding in your application object. Binding in the application object has its own difficulties, since it is never clear exactly when the application ends, so you have to find signals that come close enough to indicating the application is closed. One that I have used is the onTrimMemory() method. For example, check if the parameter is >= TRIM_MEMORY_BACKGROUND and it would be a good signal that your app is no longer in use, and it is a good time to stop the service (by unbinding from it). It is a little more difficult to get a good prediction of when the application comes back to the foreground. Say for example the user stops using the app for an hour, the OS sends the TimMemory() method, but does not kill the application. Then the user re-launches the application. You may be without the service.

A method I use to get around this is to have activities register with the application in their onResume() method and deregister in their onPause() method. This way, I can detect when the application comes to the foreground (there are 1+ registered activities) and when it goes to the background (0 registered activities). When the first activity registers, I bind the services, when the last one deregisters I unbind the service - letting it die (this usually allows the service to end sooner than waiting for the onTrimMemory() callback, which I see as a positive in terms of consuming less of a user's battery and bandwidth). I also have the application provide the IBinder to any interested activities so they can communicate with the service when required.

I agree. Here's the link:
subject: Service being destroyed?
It's not a secret anymore!