| page.title=Bound Services | |
| parent.title=Services | |
| parent.link=services.html | |
| @jd:body | |
| <div id="qv-wrapper"> | |
| <ol id="qv"> | |
| <h2>Quickview</h2> | |
| <ul> | |
| <li>A bound service allows other components to bind to it, in order to interact with it and | |
| perform interprocess communication</li> | |
| <li>A bound service is destroyed once all clients unbind, unless the service was also started</li> | |
| </ul> | |
| <h2>In this document</h2> | |
| <ol> | |
| <li><a href="#Basics">The Basics</a></li> | |
| <li><a href="#Creating">Creating a Bound Service</a> | |
| <ol> | |
| <li><a href="#Binder">Extending the Binder class</a></li> | |
| <li><a href="#Messenger">Using a Messenger</a></li> | |
| </ol> | |
| </li> | |
| <li><a href="#Binding">Binding to a Service</a></li> | |
| <li><a href="#Lifecycle">Managing the Lifecycle of a Bound Service</a></li> | |
| </ol> | |
| <h2>Key classes</h2> | |
| <ol> | |
| <li>{@link android.app.Service}</li> | |
| <li>{@link android.content.ServiceConnection}</li> | |
| <li>{@link android.os.IBinder}</li> | |
| </ol> | |
| <h2>Samples</h2> | |
| <ol> | |
| <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code | |
| RemoteService}</a></li> | |
| <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code | |
| LocalService}</a></li> | |
| </ol> | |
| <h2>See also</h2> | |
| <ol> | |
| <li><a href="{@docRoot}guide/components/services.html">Services</a></li> | |
| </ol> | |
| </div> | |
| <p>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.</p> | |
| <p>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 <a | |
| href="{@docRoot}guide/components/services.html">Services</a> 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.</p> | |
| <h2 id="Basics">The Basics</h2> | |
| <p>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.</p> | |
| <div class="sidebox-wrapper"> | |
| <div class="sidebox"> | |
| <h3>Binding to a Started Service</h3> | |
| <p>As discussed in the <a href="{@docRoot}guide/components/services.html">Services</a> | |
| document, you can create a service that is both started and bound. That is, the service can be | |
| started by calling {@link android.content.Context#startService startService()}, which allows the | |
| service to run indefinitely, and also allow a client to bind to the service by calling {@link | |
| android.content.Context#bindService bindService()}. | |
| <p>If you do allow your service to be started and bound, then when the service has been | |
| started, the system does <em>not</em> destroy the service when all clients unbind. Instead, you must | |
| explicitly stop the service, by calling {@link android.app.Service#stopSelf stopSelf()} or {@link | |
| android.content.Context#stopService stopService()}.</p> | |
| <p>Although you should usually implement either {@link android.app.Service#onBind onBind()} | |
| <em>or</em> {@link android.app.Service#onStartCommand onStartCommand()}, it's sometimes necessary to | |
| implement both. For example, a music player might find it useful to allow its service to run | |
| indefinitely and also provide binding. This way, an activity can start the service to play some | |
| music and the music continues to play even if the user leaves the application. Then, when the user | |
| returns to the application, the activity can bind to the service to regain control of playback.</p> | |
| <p>Be sure to read the section about <a href="#Lifecycle">Managing the Lifecycle of a Bound | |
| Service</a>, for more information about the service lifecycle when adding binding to a | |
| started service.</p> | |
| </div> | |
| </div> | |
| <p>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.</p> | |
| <p>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.</p> | |
| <p>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()}).</p> | |
| <p>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.</p> | |
| <h2 id="Creating">Creating a Bound Service</h2> | |
| <p>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:</p> | |
| <dl> | |
| <dt><a href="#Binder">Extending the Binder class</a></dt> | |
| <dd>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}. | |
| <p>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.</dd> | |
| <dt><a href="#Messenger">Using a Messenger</a></dt> | |
| <dd>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. | |
| <p>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.</p> | |
| </dd> | |
| <dt>Using AIDL</dt> | |
| <dd>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. | |
| <p>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.</p> | |
| </dd> | |
| </dl> | |
| <p class="note"><strong>Note:</strong> Most applications <strong>should not</strong> 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 <a href="{@docRoot}guide/components/aidl.html">AIDL</a> | |
| document.</p> | |
| <h3 id="Binder">Extending the Binder class</h3> | |
| <p>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.</p> | |
| <p class="note"><strong>Note:</strong> 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.</p> | |
| <p>Here's how to set it up:</p> | |
| <ol> | |
| <li>In your service, create an instance of {@link android.os.Binder} that either: | |
| <ul> | |
| <li>contains public methods that the client can call</li> | |
| <li>returns the current {@link android.app.Service} instance, which has public methods the | |
| client can call</li> | |
| <li>or, returns an instance of another class hosted by the service with public methods the | |
| client can call</li> | |
| </ul> | |
| <li>Return this instance of {@link android.os.Binder} from the {@link | |
| android.app.Service#onBind onBind()} callback method.</li> | |
| <li>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.</li> | |
| </ol> | |
| <p class="note"><strong>Note:</strong> 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.</p> | |
| <p>For example, here's a service that provides clients access to methods in the service through | |
| a {@link android.os.Binder} implementation:</p> | |
| <pre> | |
| 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); | |
| } | |
| } | |
| </pre> | |
| <p>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.</p> | |
| <p>Here's an activity that binds to {@code LocalService} and calls {@code getRandomNumber()} | |
| when a button is clicked:</p> | |
| <pre> | |
| 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; | |
| } | |
| }; | |
| } | |
| </pre> | |
| <p>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.</p> | |
| <p class="note"><strong>Note:</strong> 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).</p> | |
| <p>For more sample code, see the <a | |
| href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code | |
| LocalService.java}</a> class and the <a | |
| href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code | |
| LocalServiceActivities.java}</a> class in <a | |
| href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p> | |
| <h3 id="Messenger">Using a Messenger</h3> | |
| <div class="sidebox-wrapper"> | |
| <div class="sidebox"> | |
| <h4>Compared to AIDL</h4> | |
| <p>When you need to perform IPC, using a {@link android.os.Messenger} for your interface is | |
| simpler than implementing it with AIDL, because {@link android.os.Messenger} queues | |
| all calls to the service, whereas, a pure AIDL interface sends simultaneous requests to the | |
| service, which must then handle multi-threading.</p> | |
| <p>For most applications, the service doesn't need to perform multi-threading, so using a {@link | |
| android.os.Messenger} allows the service to handle one call at a time. If it's important | |
| that your service be multi-threaded, then you should use <a | |
| href="{@docRoot}guide/components/aidl.html">AIDL</a> to define your interface.</p> | |
| </div> | |
| </div> | |
| <p>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.</p> | |
| <p>Here's a summary of how to use a {@link android.os.Messenger}:</p> | |
| <ul> | |
| <li>The service implements a {@link android.os.Handler} that receives a callback for each | |
| call from a client.</li> | |
| <li>The {@link android.os.Handler} is used to create a {@link android.os.Messenger} object | |
| (which is a reference to the {@link android.os.Handler}).</li> | |
| <li>The {@link android.os.Messenger} creates an {@link android.os.IBinder} that the service | |
| returns to clients from {@link android.app.Service#onBind onBind()}.</li> | |
| <li>Clients use the {@link android.os.IBinder} to instantiate the {@link android.os.Messenger} | |
| (that references the service's {@link android.os.Handler}), which the client uses to send | |
| {@link android.os.Message} objects to the service.</li> | |
| <li>The service receives each {@link android.os.Message} in its {@link | |
| android.os.Handler}—specifically, in the {@link android.os.Handler#handleMessage | |
| handleMessage()} method.</li> | |
| </ul> | |
| <p>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}.</p> | |
| <p>Here's a simple example service that uses a {@link android.os.Messenger} interface:</p> | |
| <pre> | |
| 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(); | |
| } | |
| } | |
| </pre> | |
| <p>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.</p> | |
| <p>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:</p> | |
| <pre> | |
| 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; | |
| } | |
| } | |
| } | |
| </pre> | |
| <p>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.</p> | |
| <p>You can see an example of how to provide two-way messaging in the <a | |
| href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code | |
| MessengerService.java}</a> (service) and <a | |
| href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code | |
| MessengerServiceActivities.java}</a> (client) samples.</p> | |
| <h2 id="Binding">Binding to a Service</h2> | |
| <p>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.</p> | |
| <p>The binding is asynchronous. {@link android.content.Context#bindService | |
| bindService()} returns immediately and does <em>not</em> 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}.</p> | |
| <p class="note"><strong>Note:</strong> Only activities, services, and content providers can bind | |
| to a service—you <strong>cannot</strong> bind to a service from a broadcast receiver.</p> | |
| <p>So, to bind to a service from your client, you must: </p> | |
| <ol> | |
| <li>Implement {@link android.content.ServiceConnection}. | |
| <p>Your implementation must override two callback methods:</p> | |
| <dl> | |
| <dt>{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}</dt> | |
| <dd>The system calls this to deliver the {@link android.os.IBinder} returned by | |
| the service's {@link android.app.Service#onBind onBind()} method.</dd> | |
| <dt>{@link android.content.ServiceConnection#onServiceDisconnected | |
| onServiceDisconnected()}</dt> | |
| <dd>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 <em>not</em> called when the | |
| client unbinds.</dd> | |
| </dl> | |
| </li> | |
| <li>Call {@link | |
| android.content.Context#bindService bindService()}, passing the {@link | |
| android.content.ServiceConnection} implementation. </li> | |
| <li>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.</li> | |
| <li>To disconnect from the service, call {@link | |
| android.content.Context#unbindService unbindService()}. | |
| <p>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.)</p> | |
| </li> | |
| </ol> | |
| <p>For example, the following snippet connects the client to the service created above by | |
| <a href="#Binder">extending the Binder class</a>, so all it must do is cast the returned | |
| {@link android.os.IBinder} to the {@code LocalService} class and request the {@code | |
| LocalService} instance:</p> | |
| <pre> | |
| 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; | |
| } | |
| }; | |
| </pre> | |
| <p>With this {@link android.content.ServiceConnection}, the client can bind to a service by passing | |
| it to {@link android.content.Context#bindService bindService()}. For example:</p> | |
| <pre> | |
| Intent intent = new Intent(this, LocalService.class); | |
| bindService(intent, mConnection, Context.BIND_AUTO_CREATE); | |
| </pre> | |
| <ul> | |
| <li>The first parameter of {@link android.content.Context#bindService bindService()} is an | |
| {@link android.content.Intent} that explicitly names the service to bind (thought the intent | |
| could be implicit).</li> | |
| <li>The second parameter is the {@link android.content.ServiceConnection} object.</li> | |
| <li>The third parameter is a flag indicating options for the binding. It should usually be {@link | |
| android.content.Context#BIND_AUTO_CREATE} in order to create the service if its not already alive. | |
| Other possible values are {@link android.content.Context#BIND_DEBUG_UNBIND} | |
| and {@link android.content.Context#BIND_NOT_FOREGROUND}, or {@code 0} for none.</li> | |
| </ul> | |
| <h3>Additional notes</h3> | |
| <p>Here are some important notes about binding to a service:</p> | |
| <ul> | |
| <li>You should always trap {@link android.os.DeadObjectException} exceptions, which are thrown | |
| when the connection has broken. This is the only exception thrown by remote methods.</li> | |
| <li>Objects are reference counted across processes. </li> | |
| <li>You should usually pair the binding and unbinding during | |
| matching bring-up and tear-down moments of the client's lifecycle. For example: | |
| <ul> | |
| <li>If you only need to interact with the service while your activity is visible, you | |
| should bind during {@link android.app.Activity#onStart onStart()} and unbind during {@link | |
| android.app.Activity#onStop onStop()}.</li> | |
| <li>If you want your activity to receive responses even while it is stopped in the | |
| background, then you can bind during {@link android.app.Activity#onCreate onCreate()} and unbind | |
| during {@link android.app.Activity#onDestroy onDestroy()}. Beware that this implies that your | |
| activity needs to use the service the entire time it's running (even in the background), so if | |
| the service is in another process, then you increase the weight of the process and it becomes | |
| more likely that the system will kill it.</li> | |
| </ul> | |
| <p class="note"><strong>Note:</strong> You should usually <strong>not</strong> bind and unbind | |
| during your activity's {@link android.app.Activity#onResume onResume()} and {@link | |
| android.app.Activity#onPause onPause()}, because these callbacks occur at every lifecycle transition | |
| and you should keep the processing that occurs at these transitions to a minimum. Also, if | |
| multiple activities in your application bind to the same service and there is a transition between | |
| two of those activities, the service may be destroyed and recreated as the current activity unbinds | |
| (during pause) before the next one binds (during resume). (This activity transition for how | |
| activities coordinate their lifecycles is described in the <a | |
| href="{@docRoot}guide/components/activities.html#CoordinatingActivities">Activities</a> | |
| document.)</p> | |
| </ul> | |
| <p>For more sample code, showing how to bind to a service, see the <a | |
| href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code | |
| RemoteService.java}</a> class in <a | |
| href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p> | |
| <h2 id="Lifecycle">Managing the Lifecycle of a Bound Service</h2> | |
| <p>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.</p> | |
| <p>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 <em>started</em>. 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.</p> | |
| <p>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.</p> | |
| <img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" /> | |
| <p class="img-caption"><strong>Figure 1.</strong> The lifecycle for a service that is started | |
| and also allows binding.</p> | |
| <p>For more information about the lifecycle of a started service, see the <a | |
| href="{@docRoot}guide/components/services.html#Lifecycle">Services</a> document.</p> | |