37

I want a service which can run in the background until I stop, even if the component that started it is destroyed and also allows binding to the activities. How it is possible ?

As per android bound services document - there are three ways of creating bound service

  1. Extending Binder class.
  2. Using Messenger.
  3. Using AIDL.

I have created a bound service using messenger (2nd method). Activity is bind to service in its onStart() method and unbind in its onStop() method. Two way messaging (between activity and service) works properly. But problem is that when activity unbinds service, service is destroyed. But I want a service which can run indefinitely.

It is possible as android Services Dev Guide - "Although this documentation generally discusses these two types of services separately, your service can work both ways—it can be started (to run indefinitely) and also allow binding. It's simply a matter of whether you implement a couple callback methods: onStartCommand() to allow components to start it and onBind() to allow binding."

I also implement onStartCommand() method in service and return START_STICKY, but it is never called. Looking at the lifecycle callbacks of bounded service in dev guide, there is no onStartCommand() callback method. Then how it is possible to run service until we stop and also allow binding?

I am using eclipse platform in fedora 15 OS.

Any Help.....

Khushbu Shah
  • 1,691
  • 3
  • 23
  • 41
  • 5
    "I want a service which can run in the background indefinitely" -- This is not possible. The user will kill your service if they feel that you are wasting their device resources without continuously delivering value. The OS will kill your service if it feels that it has been running too long. I would guess that less than 0.1% of Android applications need an everlasting service. Convince us that your application really needs a service that runs all of the time. – CommonsWare Sep 03 '11 at 11:59
  • 1
    I want a service which starts when my app starts and can run until user select exit from option menu in my app or user or OS will kill it.The problem is that user start my app so my service is started (I use bound service because I want to communicate activities and service using messenger), but it is destroyed when user pressed back and come to the home screen because my activity is unbind in its onStop() method, and when all activity unbinds my service is destroyed which I don't want because I listen SIP messages coming from background and according to message update activity when it starts. – Khushbu Shah Sep 05 '11 at 04:43
  • why do you want it to run indefinitely? What is the thing you want it to always execute? – Sherif elKhatib Sep 07 '11 at 10:41
  • The answer is don't ... I did this ... it kills your battery – Moog Sep 13 '11 at 15:01
  • 24
    This is a really bad attitude to have here. Explain to him why it's a bad idea, and then explain how to do it anyway. StackOverflow is the defacto source for answers to a lot of these problems on the web, and while he may not have a valid case, other people may. This adds no value to people searching on the web for an answer. – Hounshell Apr 24 '13 at 21:01

6 Answers6

47

You just need to start it with startService() somewhere. This will prevent it from being stopped automatically when there are no more bindings.

From the Service documentation, emphasis mine:

A service can be both started and have connections bound to it. In such a case, the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE flag.

As others have pointed out, it could still be killed by Android if resources are needed. You can "prioritize" your Service and make it less likely to be killed if you make it a foreground service.

Joel F
  • 2,571
  • 1
  • 16
  • 17
  • 2
    This is (at least) not always true. I started the service using startService and then bound to it. When the last binder releases the bind, the service is killed. The service runs in a separate process. – Harmen Nov 25 '15 at 11:58
6

I've not used services with the messenger service, but I have bound to a remote service with a remote (AIDL) interface. My findings may be of some help. As my main activity and service are currently implemented, I bind to the service like you do with code like

mServiceConnected = bindService(new Intent("com.mypackage.MyService.SERVICE"), this,
                Context.BIND_AUTO_CREATE);

My activity implements ServiceConnection

When I call unbindService(this) as the activity ends, then like you have found, the service's onDestroy() method is called.

If however, prior to the bindService line, I also explicitly start the service with

startService(new Intent("com.mypackage.MyService.SERVICE"));

then the unBind does not cause the service's onDestroy() to execute. It's still necessary call unbindService in the activity's onDestroy/Stop, otherwise you will leak a service connection.

In my case, presumably the service remains available for other applications to bind to via its remote interface.

NickT
  • 23,183
  • 11
  • 76
  • 115
  • I don't know very much about remote service (AIDL interface). Can you explain why and where it is used ? I read android document and I found that " Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service." So I think I don't need it. In my application I'm listening for SIP messages and according to that update ui and send response. I'm confused about AIDL. Can you give your suggestion? – Khushbu Shah Sep 14 '11 at 05:39
  • @Khushbu - I only used a remote service and AIDL because I wanted the service in a separate apk from the main app. In your case you can still use both bindService and startService on a local service. – NickT Sep 14 '11 at 07:13
3

Service.onStartCommand callback will be called only when you start your service using startService method. As @NickT and @JoelF already pointed you need to call startService() besides the bindService() call somewhere in your client code (e.g. in onCreate).

You might also want to have a look at this (a little bit old, but still useful) article: "Double life of a service" and try the example program author provided.

Idolon
  • 26,581
  • 12
  • 93
  • 121
2

In order to perform communication between service and activity. You can also use Binder as mentioned in Official Android Example

http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

As official android documents suggests http://developer.android.com/guide/components/services.html#StartingAService

Although this documentation generally discusses these two types of services separately, your service can work both ways—it can be started (to run indefinitely) and also allow binding. It's simply a matter of whether you implement a couple callback methods: onStartCommand() to allow components to start it and onBind() to allow binding.

This project implement this mixture of service (BothService) and shows that how can a Service run indefinitely and also allow binding with multiple activities.

https://github.com/shanrais/BothService

shanraisshan
  • 3,073
  • 1
  • 15
  • 39
1

If you add the "Ongoing Notification" in the Android App Drawer, then your app and service won't be killed.

Check out http://developer.android.com/guide/topics/ui/notifiers/notifications.html

Abhijeet Pathak
  • 1,866
  • 3
  • 19
  • 28
0

You can use service binder and make a single instance of connection at app instance level, in onCreate of the App, this will keep service alive. The service must be foreground service

Qumber Abbas
  • 200
  • 1
  • 10