page.title=Bound Services parent.title=Services parent.link=services.html @jd:body

    Quickview

    In this document

    1. The Basics
    2. Creating a Bound Service
      1. Extending the Binder class
      2. Using a Messenger
    3. Binding to a Service
    4. Managing the Lifecycle of a Bound Service

    Key classes

    1. {@link android.app.Service}
    2. {@link android.content.ServiceConnection}
    3. {@link android.os.IBinder}

    Samples

    1. {@code RemoteService}
    2. {@code LocalService}

    See also

    1. Services

A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication (IPC). A bound service typically lives only while it serves another application component and does not run in the background indefinitely.

This document shows you how to create a bound service, including how to bind to the service from other application components. However, you should also refer to the Services document for additional information about services in general, such as how to deliver notifications from a service, set the service to run in the foreground, and more.

The Basics

A bound service is an implementation of the {@link android.app.Service} class that allows other applications to bind to it and interact with it. To provide binding for a service, you must implement the {@link android.app.Service#onBind onBind()} callback method. This method returns an {@link android.os.IBinder} object that defines the programming interface that clients can use to interact with the service.

A client can bind to the service by calling {@link android.content.Context#bindService bindService()}. When it does, it must provide an implementation of {@link android.content.ServiceConnection}, which monitors the connection with the service. The {@link android.content.Context#bindService bindService()} method returns immediately without a value, but when the Android system creates the connection between the client and service, it calls {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} on the {@link android.content.ServiceConnection}, to deliver the {@link android.os.IBinder} that the client can use to communicate with the service.

Multiple clients can connect to the service at once. However, the system calls your service's {@link android.app.Service#onBind onBind()} method to retrieve the {@link android.os.IBinder} only when the first client binds. The system then delivers the same {@link android.os.IBinder} to any additional clients that bind, without calling {@link android.app.Service#onBind onBind()} again.

When the last client unbinds from the service, the system destroys the service (unless the service was also started by {@link android.content.Context#startService startService()}).

When you implement your bound service, the most important part is defining the interface that your {@link android.app.Service#onBind onBind()} callback method returns. There are a few different ways you can define your service's {@link android.os.IBinder} interface and the following section discusses each technique.

Creating a Bound Service

When creating a service that provides binding, you must provide an {@link android.os.IBinder} that provides the programming interface that clients can use to interact with the service. There are three ways you can define the interface:

Extending the Binder class
If your service is private to your own application and runs in the same process as the client (which is common), you should create your interface by extending the {@link android.os.Binder} class and returning an instance of it from {@link android.app.Service#onBind onBind()}. The client receives the {@link android.os.Binder} and can use it to directly access public methods available in either the {@link android.os.Binder} implementation or even the {@link android.app.Service}.

This is the preferred technique when your service is merely a background worker for your own application. The only reason you would not create your interface this way is because your service is used by other applications or across separate processes.

Using a Messenger
If you need your interface to work across different processes, you can create an interface for the service with a {@link android.os.Messenger}. In this manner, the service defines a {@link android.os.Handler} that responds to different types of {@link android.os.Message} objects. This {@link android.os.Handler} is the basis for a {@link android.os.Messenger} that can then share an {@link android.os.IBinder} with the client, allowing the client to send commands to the service using {@link android.os.Message} objects. Additionally, the client can define a {@link android.os.Messenger} of its own so the service can send messages back.

This is the simplest way to perform interprocess communication (IPC), because the {@link android.os.Messenger} queues all requests into a single thread so that you don't have to design your service to be thread-safe.

Using AIDL
AIDL (Android Interface Definition Language) performs all the work to decompose objects into primitives that the operating system can understand and marshall them across processes to perform IPC. The previous technique, using a {@link android.os.Messenger}, is actually based on AIDL as its underlying structure. As mentioned above, the {@link android.os.Messenger} creates a queue of all the client requests in a single thread, so the service receives requests one at a time. If, however, you want your service to handle multiple requests simultaneously, then you can use AIDL directly. In this case, your service must be capable of multi-threading and be built thread-safe.

To use AIDL directly, you must create an {@code .aidl} file that defines the programming interface. The Android SDK tools use this file to generate an abstract class that implements the interface and handles IPC, which you can then extend within your service.

Note: Most applications should not use AIDL to create a bound service, because it may require multithreading capabilities and can result in a more complicated implementation. As such, AIDL is not suitable for most applications and this document does not discuss how to use it for your service. If you're certain that you need to use AIDL directly, see the AIDL document.

Extending the Binder class

If your service is used only by the local application and does not need to work across processes, then you can implement your own {@link android.os.Binder} class that provides your client direct access to public methods in the service.

Note: This works only if the client and service are in the same application and process, which is most common. For example, this would work well for a music application that needs to bind an activity to its own service that's playing music in the background.

Here's how to set it up:

  1. In your service, create an instance of {@link android.os.Binder} that either:
  2. Return this instance of {@link android.os.Binder} from the {@link android.app.Service#onBind onBind()} callback method.
  3. In the client, receive the {@link android.os.Binder} from the {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method and make calls to the bound service using the methods provided.

Note: The reason the service and client must be in the same application is so the client can cast the returned object and properly call its APIs. The service and client must also be in the same process, because this technique does not perform any marshalling across processes.

For example, here's a service that provides clients access to methods in the service through a {@link android.os.Binder} implementation:

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    // Random number generator
    private final Random mGenerator = new Random();

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}

The {@code LocalBinder} provides the {@code getService()} method for clients to retrieve the current instance of {@code LocalService}. This allows clients to call public methods in the service. For example, clients can call {@code getRandomNumber()} from the service.

Here's an activity that binds to {@code LocalService} and calls {@code getRandomNumber()} when a button is clicked:

public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to LocalService
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }

    /** Called when a button is clicked (the button in the layout file attaches to
      * this method with the android:onClick attribute) */
    public void onButtonClick(View v) {
        if (mBound) {
            // Call a method from the LocalService.
            // However, if this call were something that might hang, then this request should
            // occur in a separate thread to avoid slowing down the activity performance.
            int num = mService.getRandomNumber();
            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
        }
    }

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

The above sample shows how the client binds to the service using an implementation of {@link android.content.ServiceConnection} and the {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback. The next section provides more information about this process of binding to the service.

Note: The example above doesn't explicitly unbind from the service, but all clients should unbind at an appropriate time (such as when the activity pauses).

For more sample code, see the {@code LocalService.java} class and the {@code LocalServiceActivities.java} class in ApiDemos.

Using a Messenger

If you need your service to communicate with remote processes, then you can use a {@link android.os.Messenger} to provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.

Here's a summary of how to use a {@link android.os.Messenger}:

In this way, there are no "methods" for the client to call on the service. Instead, the client delivers "messages" ({@link android.os.Message} objects) that the service receives in its {@link android.os.Handler}.

Here's a simple example service that uses a {@link android.os.Messenger} interface:

public class MessengerService extends Service {
    /** Command to the service to display a message */
    static final int MSG_SAY_HELLO = 1;

    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}

Notice that the {@link android.os.Handler#handleMessage handleMessage()} method in the {@link android.os.Handler} is where the service receives the incoming {@link android.os.Message} and decides what to do, based on the {@link android.os.Message#what} member.

All that a client needs to do is create a {@link android.os.Messenger} based on the {@link android.os.IBinder} returned by the service and send a message using {@link android.os.Messenger#send send()}. For example, here's a simple activity that binds to the service and delivers the {@code MSG_SAY_HELLO} message to the service:

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;

    /** Flag indicating whether we have called bind on the service. */
    boolean mBound;

    /**
     * Class for interacting with the main interface of the service.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = new Messenger(service);
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound = false;
        }
    };

    public void sayHello(View v) {
        if (!mBound) return;
        // Create and send a message to the service, using a supported 'what' value
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to the service
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

Notice that this example does not show how the service can respond to the client. If you want the service to respond, then you need to also create a {@link android.os.Messenger} in the client. Then when the client receives the {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it sends a {@link android.os.Message} to the service that includes the client's {@link android.os.Messenger} in the {@link android.os.Message#replyTo} parameter of the {@link android.os.Messenger#send send()} method.

You can see an example of how to provide two-way messaging in the {@code MessengerService.java} (service) and {@code MessengerServiceActivities.java} (client) samples.

Binding to a Service

Application components (clients) can bind to a service by calling {@link android.content.Context#bindService bindService()}. The Android system then calls the service's {@link android.app.Service#onBind onBind()} method, which returns an {@link android.os.IBinder} for interacting with the service.

The binding is asynchronous. {@link android.content.Context#bindService bindService()} returns immediately and does not return the {@link android.os.IBinder} to the client. To receive the {@link android.os.IBinder}, the client must create an instance of {@link android.content.ServiceConnection} and pass it to {@link android.content.Context#bindService bindService()}. The {@link android.content.ServiceConnection} includes a callback method that the system calls to deliver the {@link android.os.IBinder}.

Note: Only activities, services, and content providers can bind to a service—you cannot bind to a service from a broadcast receiver.

So, to bind to a service from your client, you must:

  1. Implement {@link android.content.ServiceConnection}.

    Your implementation must override two callback methods:

    {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}
    The system calls this to deliver the {@link android.os.IBinder} returned by the service's {@link android.app.Service#onBind onBind()} method.
    {@link android.content.ServiceConnection#onServiceDisconnected onServiceDisconnected()}
    The Android system calls this when the connection to the service is unexpectedly lost, such as when the service has crashed or has been killed. This is not called when the client unbinds.
  2. Call {@link android.content.Context#bindService bindService()}, passing the {@link android.content.ServiceConnection} implementation.
  3. When the system calls your {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method, you can begin making calls to the service, using the methods defined by the interface.
  4. To disconnect from the service, call {@link android.content.Context#unbindService unbindService()}.

    When your client is destroyed, it will unbind from the service, but you should always unbind when you're done interacting with the service or when your activity pauses so that the service can shutdown while its not being used. (Appropriate times to bind and unbind is discussed more below.)

For example, the following snippet connects the client to the service created above by extending the Binder class, so all it must do is cast the returned {@link android.os.IBinder} to the {@code LocalService} class and request the {@code LocalService} instance:

LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
    // Called when the connection with the service is established
    public void onServiceConnected(ComponentName className, IBinder service) {
        // Because we have bound to an explicit
        // service that is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    // Called when the connection with the service disconnects unexpectedly
    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "onServiceDisconnected");
        mBound = false;
    }
};

With this {@link android.content.ServiceConnection}, the client can bind to a service by passing this it to {@link android.content.Context#bindService bindService()}. For example:

Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

Additional notes

Here are some important notes about binding to a service:

For more sample code, showing how to bind to a service, see the {@code RemoteService.java} class in ApiDemos.

Managing the Lifecycle of a Bound Service

Figure 1. The lifecycle for a service that is started and also allows binding.

When a service is unbound from all clients, the Android system destroys it (unless it was also started with {@link android.app.Service#onStartCommand onStartCommand()}). As such, you don't have to manage the lifecycle of your service if it's purely a bound service—the Android system manages it for you based on whether it is bound to any clients.

However, if you choose to implement the {@link android.app.Service#onStartCommand onStartCommand()} callback method, then you must explicitly stop the service, because the service is now considered to be started. In this case, the service runs until the service stops itself with {@link android.app.Service#stopSelf()} or another component calls {@link android.content.Context#stopService stopService()}, regardless of whether it is bound to any clients.

Additionally, if your service is started and accepts binding, then when the system calls your {@link android.app.Service#onUnbind onUnbind()} method, you can optionally return {@code true} if you would like to receive a call to {@link android.app.Service#onRebind onRebind()} the next time a client binds to the service (instead of receiving a call to {@link android.app.Service#onBind onBind()}). {@link android.app.Service#onRebind onRebind()} returns void, but the client still receives the {@link android.os.IBinder} in its {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback. Below, figure 1 illustrates the logic for this kind of lifecycle.

For more information about the lifecycle of an started service, see the Services document.