20

In my Android app, I call both startService and bindService:

Intent intent = new Intent(this, MyService.class);
ServiceConnection conn = new ServiceConnection() { ... }

startService(intent)
bindService(intent, conn, BIND_AUTO_CREATE);

Later, I attempt to both unbindService andstopService`:

unbindService(conn);
stopService(intent);

However, I get an exception on the call to unbindService. If I remove this call, the app seems to run properly through the stopService call.

Am I doing something wrong? I thought a bindService call had to be associated with an unbindService call, and a startService call had to be associated with a stopService call. This doesn't seem to be the case here, though.

Matt Huggins
  • 81,398
  • 36
  • 149
  • 218
  • Did you ever figure this out? I ran into the same thing, and commented out the unbindService(conn) for myself. Seems to work okay, but just like you, my gut says something in the background wouldn't like it. – David Liu Dec 16 '10 at 03:34

4 Answers4

30

The Android documentation for stopService() states:

Note that if a stopped service still has ServiceConnection objects bound to it with the BIND_AUTO_CREATE set, it will not be destroyed until all of these bindings are removed. See the Service documentation for more details on a service's lifecycle.

So calling stopService() first followed by unbindService() should work (it's working for me).

Mike Lowery
  • 2,630
  • 4
  • 34
  • 44
  • 2
    Ahh, so it sounds like my ordering of `unbindService` and `stopService` were backwards, I see. – Matt Huggins Feb 20 '11 at 21:04
  • Thanks, this helped me! I had BIND_AUTO_CREATE used and unbindService() helped to solve the problem with ServiceConnection leak. – lomza Jan 30 '13 at 09:30
  • @Matt Huggins so you guys mean to unbind first and then stop is it? – Mr.Noob Nov 19 '14 at 12:40
  • Calling stopService first then unbindService works for me. – chengsam Oct 13 '16 at 05:03
  • `the service runs until the service stops itself with stopSelf() or another component calls stopService(), regardless of whether it is bound to any clients.` https://developer.android.com/guide/components/bound-services#Lifecycle – xuiqzy Sep 18 '20 at 12:15
8

A gotcha that I hit with this:

Ensure you call unbindService on the same context that you called bindService. In my case, I was doing the following to bind it:

Context c = getApplicationContext();
c.bindService(...);

Then to unbind it, just:

unbindService(...);

Making sure both bind and unbind used the same context solved the problem.

rmc47
  • 1,364
  • 1
  • 13
  • 17
5

As you can see here it depends what you want to achieve and how you bind the service. If you want to have a long time reference to the service, it is better to use bindService than startService. If in the bindService method, the flag BIND_AUTO_CREATE is used, then you don't have to call startService, because the service starts itself when necessary.

If you call unBind service, then you assoication to the service is deleted. You dont' have to explicitly stop the service but you can. But it's importatnt to note, that if you call unBind(), then the service is allowed to stop at any time.

RoflcoptrException
  • 51,941
  • 35
  • 152
  • 200
  • 2
    Thanks, but I've been there, and it's not clear if I need to both unbind and stop the service if I manually started it before binding to it with the BIND_AUTO_CREATE flag. – Matt Huggins Aug 05 '10 at 16:28
  • `But it's importatnt to note, that if you call unBind(), then the service is allowed to stop at any time.` — No, if it was started, it will not stop until a call to `stopSelf` or `stopService`: `the service runs until the service stops itself with stopSelf() or another component calls stopService(), regardless of whether it is bound to any clients.` https://developer.android.com/guide/components/bound-services#Lifecycle – xuiqzy Sep 18 '20 at 12:16
0

To answer you question directly, it is "okay" to not call unbindservice BUT it is not recommended. What happens is if your service is not a foreground service, android system may kills it to free up memory. And if there is still some component bounded to it, but you haven't called unbind, it gets unbound by the android system.

See android documentation here

https://developer.android.com/guide/components/bound-services

If your client is still bound to a service when your app destroys the client, destruction causes the client to unbind. It is better practice to unbind the client as soon as it is done interacting with the service. Doing so allows the idle service to shut down. For more information about appropriate times to bind and unbind, see Additional notes.

Bqin1
  • 467
  • 1
  • 9
  • 19
  • The cited documentation seems to be about cases where the service won't be stopped when possible (because it isn't needed), but if you stop the service, it doesn't seem so clear anymore if you should and can unbind, too. – xuiqzy Sep 18 '20 at 12:12
  • `the service runs until the service stops itself with stopSelf() or another component calls stopService(), regardless of whether it is bound to any clients.` https://developer.android.com/guide/components/bound-services#Lifecycle – xuiqzy Sep 18 '20 at 12:15