5

I have an Android app, in which Activities fire long running operations that run in the background. These operations interact with the Activities when done. I'm developing a component that handles the Activity/Long-Running-Task coupling, taking care of activities being destroyed and recreated.

Right now that component is implemented as an Android service. The activities call bindService and use the resulting IBinder to start and track tasks. I decided against using startService, because I prefer the richer API possible through a Java interface.

Now the problem. Activity A start ups, binds to the service and calls serviceApi.runTask(...). Activity A is then destroyed (because the user flips the phone, for instance) and recreated as Activity A'. A' then binds again to the service, announces its existence and everything should be running nicely.

Except that my Service gets destroyed. When Activity A is destroyed, it unbinds from the service. Android sees there are no more clients, and kills the service. When Activity A' is created, the service is created again, and I lose everything the old service had.

The only solution I can see is using a singleton for the service. And then it doesn't really have to be an Android service, just an instance that's accessible to everyone. Is that frowned upon in Android? Is there a better design that fits this problem?


Editted: Even if I call startService and then bind to it, nothing guarantees that the service instance will exist as long as the application is running. Android can kill sticky services if resources are low. Killing the service will cause the application to malfunction, and I can't have that.

zmbq
  • 38,013
  • 14
  • 101
  • 171

3 Answers3

8

Even if I call startService and then bind to it, nothing guarantees that the service instance will exist as long as the application is running.

Correct.

Android can kill sticky services if resources are low.

Also correct. All "sticky" means is that Android might restart the service.

Killing the service will cause the application to malfunction, and I can't have that.

It is impossible to create a service that is guaranteed to run forever. For starters, users can get rid of your service whenever they want, because users detest developers who have pointless services that run forever. Writing everlasting services is necessary only in very few cases; otherwise, it's just sloppy programming.

The only solution I can see is using a singleton for the service. And then it doesn't really have to be an Android service, just an instance that's accessible to everyone. Is that frowned upon in Android?

Singletons (a.k.a., static data members) will go away when the process is terminated. The process will be terminated eventually, particularly if there are no active services and none of your activities is in the foreground..

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks, Commonware. The component (for lack of a better word) I have only needs to run while the application process is up and running, and the user is using it. Once the user closes the appication, the component can be shut down as well, as its sole purpose is to coordinate asyncrhonous UI-related tasks in the process. I do need a service that will periodically check the server for updates (I haven't decided on C2DM yet). I'll implement that as a short-lived service that shuts down after polling. – zmbq Nov 14 '11 at 10:52
1

Call startService and in onStartCommand return START_STICKY. It should keep the service going.

You may also want to look into foreground services:

http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification)

Kevin Galligan
  • 16,159
  • 5
  • 42
  • 62
0

Yo have to create persistent service. Refer to this manual.

In a few words - don't call bindService, call startService.

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335