Bound Services: What you should know!

  • Written by  Clive

Bound Services: a primer

Android bound services tutorial icon

Quick recap on Services

  • Services are app components that you can use to do work in the background.
  • Services run in your app’s process in the main thread. Don’t block the main thread. Use a separate thread to do any heavy work in your Service.
  • You can also use Services running in another app’s process.
  • Services continue to run until you stop them. The system can also kill them at any time but you can set their priority so that they are unlikely to be killed.

So what happens when we bind to a Service?

Bound Service diagram

A bound Service enables the client to interact with the Service

If you have not already done so, you may want to look at the following articles and tutorials:

This article covers the basics of bound Services. Our tutorial, which follows, puts everything together. You'll see how easy it is to use a bound Service in your apps!

Taking control: a bound Service

There are two types of Services:

  • A started Service – one of your app components starts the Service
  • A Bound Service – the Service acts as a server. Your app’s component (the client), logs in (binds) to the server, uses the server to do some work and then logs out (unbinds)

You can use either or both types at the same time.

The Service could already be running when you bind to it and it may continue to run after you unbind from it.

If the Service is not running, then it will start when you bind to it and stop when you unbind. As more than one client can bind to a Service at the same time, the Service will remain running until the last client has unbound from it.

Clients from other apps can also bind to your Service if you allow them to. You can also bind to other app’s Services if they allow you to.

Why use a bound Service?

You would use a started Service to do work for you if you don’t have to interact with the Service again.

You would use a bound Service if you need to interact with the service at some stage. You could also use a bound Service if you want other apps to be able to interact with parts of your app.

You’ll need an interface to interact with the Service.

The three types of Service Interface

    • Client and Service in same process

The Service and client are in the same process. Get the interface by extending the Binder class. It’s returned by onBind(). The client then uses this interface to access the public methods in the Service.  This is the most common type. We’ll show how it’s done in our tutorial

    • Client and Service in different processes

Use the following types of interface if your Service is used by other applications or across separate processes.

      • use a messenger to interact with a Service across processes. The messenger creates a queue in a single thread for all the client’s requests. The requests are then dealt with one at a time
      • use AIDL if you want your Service to handle multiple requests at the same time

Bound Service interface diagram

A bound Service is commonly used to interact with a Service when both client and Service are in the same process

The Clients

Clients are app components that bind to the Service.

These are the clients that can bind to a Service:

  • Activities
  • Services
  • Content Providers

You can’t bind to a Service from:

  • Broadcast Receivers

The Service automatically disconnects, or unbinds from the Service when the client is destroyed (unless the Service was started with startService(), in which case it will continue running until called to stop). Bear in mind that an activity is destroyed when the device changes orientation.

You should manually unbind from the Service when you don’t need it. For example, unbind from the Service when your activity pauses so that the Service can shut down and release its resources.

The ties that bind: Binding to the Service

Use bindService() to bind to a Service. This will connect to a running service. It creates the Service if it is not running.

bindService() receives three parameters:

  • intent – identifies the Service to connect to
  • the Service connection object
  • flags – these specify the options for binding:
    • BIND_AUTO_CREATE – binds to an existing Service, creating the Service if it does not exist. onStartCommand() is not called
    • BIND_DEBUG_UNBIND – should only be used for debugging
    • BIND_NOT_FOREGROUND – won’t allow the Service’s priority to be raised to that of foreground priority. Its priority will only be raised to that of the client’s priority. This is only important if the client’s process is in the foreground and the Service’s process is in the background
    • Can be 0

After the client calls bindService(), it receives an IBinder object which it uses to interact with the Service.

You can bind to an existing Service. This Service will run until it is called to stop, even if all the clients have unbound.

If it is a Service started with a call to bindService() then it will stop once all the clients have unbound.

Cut all ties: Unbinding from a Service

Multiple clients can bind to a service at once.

Call unbindService() to unbind. Once all the clients have unbound, the Service is destroyed (if the Service was started by a call to startService, then it must be stopped by a call to stopSelf() or stopService()).

If you connected to a running Service using the BIND_AUTO_CREATE , and you call stopService, the Service will not stop until all these clients have unbound.

onDestroy() is called when the Service stops. This is where you can release any resources by stopping threads and unregistering receivers for example.

Time is money: keep the Service running

Also, when using the flag, BIND_AUTO_CREATE to start a Service to bind to, the Service will not necessarily stop once all the clients have unbound. The system may allow the Service to continue running until its resources are needed elsewhere. Only then will it will be killed.  It’s cheaper to keep the Service running in case it’s needed again than to kill it and then restart it.

If you start a thread in your Service and unbind from that Service, the process in the thread will continue to run. You need to stop it to conserve resources.

The right time: When to bind and when to unbind

You should match your binding and unbinding to a Service with the client’s appropriate lifecycle methods:

  • If you need to interact with the Service while your activity is visible, then bind in onStart() and unbind in onStop()
  • If you need to interact with the Service even when it’s stopped, then bind in onCreate() and unbind in onDestroy()
  • You should usually not bind in onResume() and unbind in onPause()

The Bound Service’s Lifecycle

You don’t have to manage the lifecycle of the Service if it’s purely a bound Service. The system destroys it once all clients have unbound.

If you started a Service then you must stop it, regardless of whether any clients are bound to it.

Have a look at Binding to a Service: A Tutorial, where we show you how to bind to a Service to control a media player.

I hope that you have found this tutorial helpful.