diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java index 7c2d3a091d40c..57a26959bc8ca 100644 --- a/core/java/android/app/IntentService.java +++ b/core/java/android/app/IntentService.java @@ -113,6 +113,12 @@ public abstract class IntentService extends Service { mServiceHandler.sendMessage(msg); } + /** + * You should not override this method for your IntentService. Instead, + * override {@link #onHandleIntent}, which the system calls when the IntentService + * receives a start request. + * @see android.app.Service#onStartCommand + */ @Override public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); @@ -124,6 +130,11 @@ public abstract class IntentService extends Service { mServiceLooper.quit(); } + /** + * Unless you provide binding for your service, you don't need to implement this + * method, because the default implementation returns null. + * @see android.app.Service#onBind + */ @Override public IBinder onBind(Intent intent) { return null; @@ -135,6 +146,8 @@ public abstract class IntentService extends Service { * worker thread that runs independently from other application logic. * So, if this code takes a long time, it will hold up other requests to * the same IntentService, but it will not hold up anything else. + * When all requests have been handled, the IntentService stops itself, + * so you should not call {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. diff --git a/docs/html/guide/topics/advanced/aidl.jd b/docs/html/guide/topics/advanced/aidl.jd new file mode 100644 index 0000000000000..fef46eca464fa --- /dev/null +++ b/docs/html/guide/topics/advanced/aidl.jd @@ -0,0 +1,387 @@ +page.title=Android Interface Definition Language (AIDL) +@jd:body + + + +

AIDL (Android Interface Definition Language) is similar to other IDLs you might have +worked with. It allows you to define the programming interface that both +the client and service agree upon in order to communicate with each other and allows for +interprocess communication (IPC). On Android, one process can not normally access the +memory of another process. So to talk, they need to decompose their objects into primitives that the +operating system can understand, and "marshall" the object across that boundary for you. The code to +do that marshalling is tedious to write, so Android handles it for you with AIDL.

+ +

Note: 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. If you do not need to perform IPC across +different applications, you should create your interface implementing a +Binder or, if you want to perform IPC, but do not need to handle multithreading, then you +should implement your interface using a Messenger.

+ +

Before you begin designing your AIDL interface, be aware that calls on to an AIDL interface are +direct function calls. You can not generally make assumptions about the thread in which the call +will happen. What happens is different depending on whether the call is from a thread in the +local process, or coming from a remote process. Specifically:

+ + + + +

Defining an AIDL Interface

+ +

You must define your AIDL interface in an {@code .aidl} file using the Java +programming language syntax, then save it in the source code (in the {@code src/} directory) of both +the application hosting the service and any other application that will bind to the service.

+ +

When you build the projects containing the {@code .aidl} file, the Android SDK tools generate an +{@link android.os.IBinder} class based on your AIDL interface (and saves the file in the {@code +gen/} directory). This class defines the APIs you can call to perform RPC as an interface—you +must implement the interface in your service.

+ +

To create a bounded service using AIDL, follow these steps:

+
    +
  1. Create the .aidl file +

    This file defines the programming interface with method signatures.

    +
  2. +
  3. Implement the interface +

    The Android SDK tools generate an interface in the Java programming language, based on your +{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends +{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the +{@code Stub} class and implement the methods.

    +
  4. +
  5. Expose the interface to clients +

    Implement a {@link android.app.Service Service} and override {@link +android.app.Service#onBind onBind()} to return your implementation of the {@code Stub} +class.

    +
  6. +
+ +

Caution: Any changes that you make to your AIDL interface after +your first release must remain backward compatible in order to avoid breaking other applications +that use your service. That is, because your {@code .aidl} file must be copied to other applications +in order for them to access your service's interface, you must maintain support for the original +interface.

+ + +

1. Create the .aidl file

+ +

AIDL uses a simple syntax that lets you declare an interface with one or more methods that can +take parameters and return values. The parameters and return values can be of any type, even other +AIDL-generated interfaces.

+ +

The syntax for the {@code .aidl} file uses the Java programming language. The file defines a +single interface and requires only the interface declaration and method signatures.

+ +

By default, AIDL supports the following data types:

+ + + +

You must include an {@code import} statement for each additional type not listed above, even if +they are defined in the same package as your interface.

+ +

When defining methods for your service interface, be aware that:

+ + +

Here is an example {@code .aidl} file:

+ +
+// IRemoteService.aidl
+package com.example.android;
+
+// Declare any non-default types here with import statements
+
+/** Example service interface */
+interface IRemoteService {
+    /** Request the process ID of this service, to do evil things with it. */
+    int getPid();
+
+    /** Demonstrates some basic types that you can use as parameters
+     * and return values in AIDL.
+     */
+    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
+            double aDouble, String aString);
+}
+
+ +

Simply save your {@code .aidl} file in your project's {@code src/} directory and when you +build your application, the SDK tools will generate the binder class file in your project's +{@code gen/} directory. The generated file name matches the {@code .aidl} file name, but with a +{@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code +IRemoteService.java}).

+ +

If you use Eclipse, the incremental build generates the binder class almost immediately. If you +do not use Eclipse, then the Ant tool generates the binder class next time you build your +application—you should build your project with ant debug (or ant +release) as soon as you're finished writing the {@code .aidl} file, so that your code can +link against the generated class.

+ + +

2. Implement the interface

+ +

When you build your application, the Android SDK tools generate a {@code .java} interface file +named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub} +that is an abstract implementation of its parent interface (for example, {@code +YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.

+ +

Note: {@code Stub} also +defines a few helper methods, most notably {@code asInterface()}, which takes an {@link +android.os.IBinder} (usually the one passed to a client's {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and +returns an instance of the stub interface. See the section Calling an IPC +Method for more details on how to make this cast.

+ +

To implement the interface generated from the {@code .aidl}, extend the generated {@link +android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods +inherited from the {@code .aidl} file.

+ +

Here is an example implementation of an interface called {@code IRemoteService} (defined by the +{@code IRemoteService.aidl} example, above) using an anonymous instance:

+ +
+private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+    public int getPid(){
+        return Process.myPid();
+    }
+    public void basicTypes(int anInt, long aLong, boolean aBoolean,
+        float aFloat, double aDouble, String aString) {
+        // Does nothing
+    }
+};
+
+ +

Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}), +which defines the RPC interface for the service. In the next step, this instance is exposed to +clients so they can interact with the service.

+ +

There are a few rules you should be aware of when implementing your AIDL interface:

+ + + +

3. Expose the interface to clients

+ +

Once you've implemented the interface for your service, you need to expose it to +clients so they can bind to it. To expose the interface +for your service, extend {@link android.app.Service Service} and implement {@link +android.app.Service#onBind onBind()} to return an instance of your class that implements +the generated {@code Stub} (as discussed in the previous section). Here's an example +service that exposes the {@code IRemoteService} example interface to clients.

+ +
+public class RemoteService extends Service {
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        // Return the interface
+        return mBinder;
+    }
+
+    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+        public int getPid(){
+            return Process.myPid();
+        }
+        public void basicTypes(int anInt, long aLong, boolean aBoolean,
+            float aFloat, double aDouble, String aString) {
+            // Does nothing
+        }
+    };
+}
+
+ +

Now, when a client (such as an activity) calls {@link android.content.Context#bindService +bindService()} to connect to this service, the client's {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the +{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()} +method.

+ +

The client must also have access to the interface class, so if the client and service are in +separate applications, then the client's application must have a copy of the {@code .aidl} file +in its {@code src/} directory (which generates the {@code android.os.Binder} +interface—providing the client access to the AIDL methods).

+ +

When the client receives the {@link android.os.IBinder} in the {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call +YourServiceInterface.Stub.asInterface(service) to cast the returned +parameter to YourServiceInterface type. For example:

+ +
+IRemoteService mIRemoteService;
+private ServiceConnection mConnection = new ServiceConnection() {
+    // Called when the connection with the service is established
+    public void onServiceConnected(ComponentName className, IBinder service) {
+        // Following the example above for an AIDL interface,
+        // this gets an instance of the IRemoteInterface, which we can use to call on the service
+        mIRemoteService = IRemoteService.Stub.asInterface(service);
+    }
+
+    // Called when the connection with the service disconnects unexpectedly
+    public void onServiceDisconnected(ComponentName className) {
+        Log.e(TAG, "onServiceDisconnected");
+    }
+};
+
+ +

For more sample code, see the {@code +RemoteService.java} class in ApiDemos.

+ + + + + + + + +

Passing Objects over IPC

+ +

If you have a class that you would like to send from one process to another through +an IPC interface, you can do that. However, you must ensure that the code for your class is +available to the other side of the IPC and the class must support the {@link +android.os.Parcelable} interface, in order for the objects to be decomposed into primitives and +marshalled across processes by the Android system.

+ +

There are five parts to making a class support the {@link android.os.Parcelable} protocol: +

    +
  1. Make your class implement the {@link android.os.Parcelable} interface.
  2. +
  3. Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the +current state of the object and writes it to a {@link android.os.Parcel}.
  4. +
  5. Add a static field called CREATOR to your class which is an object implementing +the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.
  6. +
  7. Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the +{@code Rect.aidl} file, below). +

    If you are using a custom build process, do not add the {@code .aidl} file to your +build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.

  8. +
+ +

AIDL will use these methods and fields in the code it generates to marshall and unmarshall +your objects.

+ +

For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's +parcelable:

+ +
+package android.graphics;
+
+// Declare Rect so AIDL can find it and knows that it implements
+// the parcelable protocol.
+parcelable Rect;
+
+ +

And here is an example of how the {@link android.graphics.Rect} class implements the +{@link android.os.Parcelable} protocol.

+ +
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public final class Rect implements Parcelable {
+    public int left;
+    public int top;
+    public int right;
+    public int bottom;
+
+    public static final Parcelable.Creator<Rect> CREATOR = new
+Parcelable.Creator<Rect>() {
+        public Rect createFromParcel(Parcel in) {
+            return new Rect(in);
+        }
+
+        public Rect[] newArray(int size) {
+            return new Rect[size];
+        }
+    };
+
+    public Rect() {
+    }
+
+    private Rect(Parcel in) {
+        readFromParcel(in);
+    }
+
+    public void writeToParcel(Parcel out) {
+        out.writeInt(left);
+        out.writeInt(top);
+        out.writeInt(right);
+        out.writeInt(bottom);
+    }
+
+    public void readFromParcel(Parcel in) {
+        left = in.readInt();
+        top = in.readInt();
+        right = in.readInt();
+        bottom = in.readInt();
+    }
+}
+
+ +

The marshalling in the {@code Rect} class is pretty simple. Take a look at the other +methods on {@link android.os.Parcel} to see the other kinds of values you can write +to a Parcel.

+ +

Warning: Don't forget the security implications of receiving +data from other processes. In this case, the {@code Rect} will read four numbers from the {@link +android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of +values for whatever the caller is trying to do. See Security and Permissions for more +information about how to keep your application secure from malware.

+ diff --git a/docs/html/guide/topics/fundamentals/bound-services.jd b/docs/html/guide/topics/fundamentals/bound-services.jd new file mode 100644 index 0000000000000..e5d626c0799cc --- /dev/null +++ b/docs/html/guide/topics/fundamentals/bound-services.jd @@ -0,0 +1,675 @@ +page.title=Bound Services +parent.title=Services +parent.link=services.html +@jd:body + + +
+
    +

    Quickview

    + +

    In this document

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

    Key classes

    +
      +
    1. {@link android.app.Service}
    2. +
    3. {@link android.content.ServiceConnection}
    4. +
    5. {@link android.os.IBinder}
    6. +
    + +

    Samples

    +
      +
    1. {@code + RemoteService}
    2. +
    3. {@code + LocalService}
    4. +
    + +

    See also

    +
      +
    1. Services
    2. +
    +
+ + +

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. +
  4. 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.
  5. +
+ +

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. +
  3. Call {@link +android.content.Context#bindService bindService()}, passing the {@link +android.content.ServiceConnection} implementation.
  4. +
  5. 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.
  6. +
  7. 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.)

    +
  8. +
+ +

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.

+ + + + diff --git a/docs/html/guide/topics/fundamentals/services.jd b/docs/html/guide/topics/fundamentals/services.jd new file mode 100644 index 0000000000000..df1eacee50295 --- /dev/null +++ b/docs/html/guide/topics/fundamentals/services.jd @@ -0,0 +1,860 @@ +page.title=Services +parent.title=Application Fundamentals +parent.link=index.html +@jd:body + +
+
    +

    Quickview

    + +

    In this document

    +
      +
    1. The Basics
    2. +
        +
      1. Declaring a service in the manifest
      2. +
      +
    3. Creating a Started Service +
        +
      1. Extending the IntentService class
      2. +
      3. Extending the Service class
      4. +
      5. Starting a service
      6. +
      7. Stopping a service
      8. +
      +
    4. +
    5. Creating a Bound Service
    6. +
    7. Sending Notifications to the User
    8. +
    9. Running a Service in the Foreground
    10. +
    11. Managing the Lifecycle of a Service +
        +
      1. Implementing the lifecycle callbacks
      2. +
      +
    12. +
    + +

    Key classes

    +
      +
    1. {@link android.app.Service}
    2. +
    3. {@link android.app.IntentService}
    4. +
    + +

    Samples

    +
      +
    1. {@code + ServiceStartArguments}
    2. +
    3. {@code + LocalService}
    4. +
    + +

    See also

    +
      +
    1. Bound Services
    2. +
    + +
+ + +

A {@link android.app.Service} is an application component that can perform +long-running operations in the background and does not provide a user interface. Another +application component can start a service and it will continue to run in the background even if the +user switches to another application. Additionally, a component can bind to a service to +interact with it and even perform interprocess communication (IPC). For example, a service might +handle network transactions, play music, perform file I/O, or interact with a content provider, all +from the background.

+ +

A service can essentially take two forms:

+ +
+
Started
+
A service is "started" when an application component (such as an activity) starts it by +calling {@link android.content.Context#startService startService()}. Once started, a service +can run in the background indefinitely, even if the component that started it is destroyed. Usually, +a started service performs a single operation and does not return a result to the caller. +For example, it might download or upload a file over the network. When the operation is done, the +service should stop itself.
+
Bound
+
A service is "bound" when an application component binds to it by calling {@link +android.content.Context#bindService bindService()}. A bound service offers a client-server +interface that allows components to interact with the service, send requests, get results, and even +do so across processes with interprocess communication (IPC). A bound service runs only as long as +another application component is bound to it. Multiple components can bind to the service at once, +but when all of them unbind, the service is destroyed.
+
+ +

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: {@link +android.app.Service#onStartCommand onStartCommand()} to allow components to start it and {@link +android.app.Service#onBind onBind()} to allow binding.

+ +

Regardless of whether your application is started, bound, or both, any application component +can use the service (even from a separate application), in the same way that any component can use +an activity—by starting it with an {@link android.content.Intent}. However, you can declare +the service as private, in the manifest file, and block access from other applications. This is +discussed more in the section about Declaring the service in the +manifest.

+ +

Caution: A service runs in the +main thread of its hosting process—the service does not create its own thread +and does not run in a separate process (unless you specify otherwise). This means +that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 +playback or networking), you should create a new thread within the service to do that work. By using +a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the +application's main thread can remain dedicated to user interaction with your activities.

+ + +

The Basics

+ + + +

To create a service, you must create a subclass of {@link android.app.Service} (or one +of its existing subclasses). In your implementation, you need to override some callback methods that +handle key aspects of the service lifecycle and provide a mechanism for components to bind to +the service, if appropriate. The most important callback methods you should override are:

+ +
+
{@link android.app.Service#onStartCommand onStartCommand()}
+
The system calls this method when another component, such as an activity, +requests that the service be started, by calling {@link android.content.Context#startService +startService()}. Once this method executes, the service is started and can run in the +background indefinitely. If you implement this, it is your responsibility to stop the service when +its work is done, by calling {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}. (If you only want to provide binding, you don't +need to implement this method.)
+
{@link android.app.Service#onBind onBind()}
+
The system calls this method when another component wants to bind with the +service (such as to perform RPC), by calling {@link android.content.Context#bindService +bindService()}. In your implementation of this method, you must provide an interface that clients +use to communicate with the service, by returning an {@link android.os.IBinder}. You must always +implement this method, but if you don't want to allow binding, then you should return null.
+
{@link android.app.Service#onCreate()}
+
The system calls this method when the service is first created, to perform one-time setup +procedures (before it calls either {@link android.app.Service#onStartCommand onStartCommand()} or +{@link android.app.Service#onBind onBind()}). If the service is already running, this method is not +called.
+
{@link android.app.Service#onDestroy()}
+
The system calls this method when the service is no longer used and is being destroyed. +Your service should implement this to clean up any resources such as threads, registered +listeners, receivers, etc. This is the last call the service receives.
+
+ +

If a component starts the service by calling {@link +android.content.Context#startService startService()} (which results in a call to {@link +android.app.Service#onStartCommand onStartCommand()}), then the service +remains running until it stops itself with {@link android.app.Service#stopSelf()} or another +component stops it by calling {@link android.content.Context#stopService stopService()}.

+ +

If a component calls +{@link android.content.Context#bindService bindService()} to create the service (and {@link +android.app.Service#onStartCommand onStartCommand()} is not called), then the service runs +only as long as the component is bound to it. Once the service is unbound from all clients, the +system destroys it.

+ +

The Android system will force-stop a service only when memory is low and it must recover system +resources for the activity that has user focus. If the service is bound to an activity that has user +focus, then it's less likely to be killed, and if the service is declared to run in the foreground (discussed later), then it will almost never be killed. +Otherwise, if the service was started and is long-running, then the system will lower its position +in the list of background tasks over time and the service will become highly susceptible to +killing—if your service is started, then you must design it to gracefully handle restarts +by the system. If the system kills your service, it restarts it as soon as resources become +available again (though this also depends on the value you return from {@link +android.app.Service#onStartCommand onStartCommand()}, as discussed later). For more information +about when the system might destroy a service, see the Processes and Threading +document.

+ +

In the following sections, you'll see how you can create each type of service and how to use +it from other application components.

+ + + +

Declaring a service in the manifest

+ +

Like activities (and other components), you must declare all services in your application's +manifest file.

+ +

To decalare your service, add a {@code <service>} element +as a child of the {@code <application>} +element. For example:

+ +
+<manifest ... >
+  ...
+  <application ... >
+      <service android:name=".ExampleService" />
+      ...
+  </application>
+</manifest>
+
+ +

There are other attributes you can include in the {@code <service>} element to +define properties such as permissions required to start the service and the process in +which the service should run. See the {@code <service>} element +reference for more information.

+ +

Just like an activity, a service can define intent filters that allow other components to +invoke the service using implicit intents. By declaring intent filters, components +from any application installed on the user's device can potentially start your service if your +service declares an intent filter that matches the intent another application passes to {@link +android.content.Context#startService startService()}.

+ +

If you plan on using your service only locally (other applications do not use it), then you +don't need to (and should not) supply any intent filters. Without any intent filters, you must +start the service using an intent that explicitly names the service class. More information +about starting a service is discussed below.

+ +

Additionally, you can ensure that your service is private to your application only if +you include the {@code android:exported} +attribute and set it to {@code "false"}. This is effective even if your service supplies intent +filters.

+ +

For more information about creating intent filters for your service, see the Intents and Intent Filters +document.

+ + + +

Creating a Started Service

+ + + +

A started service is one that another component starts by calling {@link +android.content.Context#startService startService()}, resulting in a call to the service's +{@link android.app.Service#onStartCommand onStartCommand()} method.

+ +

When a service is started, it has a lifecycle that's independent of the +component that started it and the service can run in the background indefinitely, even if +the component that started it is destroyed. As such, the service should stop itself when its job +is done by calling {@link android.app.Service#stopSelf stopSelf()}, or another component can stop it +by calling {@link android.content.Context#stopService stopService()}.

+ +

An application component such as an activity can start the service by calling {@link +android.content.Context#startService startService()} and passing an {@link android.content.Intent} +that specifies the service and includes any data for the service to use. The service receives +this {@link android.content.Intent} in the {@link android.app.Service#onStartCommand +onStartCommand()} method.

+ +

For instance, suppose an activity needs to save some data to an online database. The activity can +start a companion service and deliver it the data to save by passing an intent to {@link +android.content.Context#startService startService()}. The service receives the intent in {@link +android.app.Service#onStartCommand onStartCommand()}, connects to the Internet and performs the +database transaction. When the transaction is done, the service stops itself and it is +destroyed.

+ +

Caution: A services runs in the same process as the application +in which it is declared and in the main thread of that application, by default. So, if your service +performs intensive or blocking operations while the user interacts with an activity from the same +application, the service will slow down activity performance. To avoid impacting application +performance, you should start a new thread inside the service.

+ +

Traditionally, there are two classes you can extend to create a started service:

+
+
{@link android.app.Service}
+
This is the base class for all services. When you extend this class, it's important that +you create a new thread in which to do all the service's work, because the service uses your +application's main thread, by default, which could slow the performance of any activity your +application is running.
+
{@link android.app.IntentService}
+
This is a subclass of {@link android.app.Service} that uses a worker thread to handle all +start requests, one at a time. This is the best option if you don't require that your service +handle multiple requests simultaneously. All you need to do is implement {@link +android.app.IntentService#onHandleIntent onHandleIntent()}, which receives the intent for each +start request so you can do the background work.
+
+ +

The following sections describe how you can implement your service using either one for these +classes.

+ + +

Extending the IntentService class

+ +

Because most started services don't need to handle multiple requests simultaneously +(which can actually be a dangerous multi-threading scenario), it's probably best if you +implement your service using the {@link android.app.IntentService} class.

+ +

The {@link android.app.IntentService} does the following:

+ + + +

All this adds up to the fact that all you need to do is implement {@link +android.app.IntentService#onHandleIntent onHandleIntent()} to do the work provided by the +client. (Though, you also need to provide a small constructor for the service.)

+ +

Here's an example implementation of {@link android.app.IntentService}:

+ +
+public class HelloIntentService extends IntentService {
+
+  /** 
+   * A constructor is required, and must call the super {@link android.app.IntentService#IntentService}
+   * constructor with a name for the worker thread.
+   */
+  public HelloIntentService() {
+      super("HelloIntentService");
+  }
+
+  /**
+   * The IntentService calls this method from the default worker thread with
+   * the intent that started the service. When this method returns, IntentService
+   * stops the service, as appropriate.
+   */
+  @Override
+  protected void onHandleIntent(Intent intent) {
+      // Normally we would do some work here, like download a file.
+      // For our sample, we just sleep for 5 seconds.
+      long endTime = System.currentTimeMillis() + 5*1000;
+      while (System.currentTimeMillis() < endTime) {
+          synchronized (this) {
+              try {
+                  wait(endTime - System.currentTimeMillis());
+              } catch (Exception e) {
+              }
+          }
+      }
+  }
+}
+
+ +

That's all you need: a constructor and an implementation of {@link +android.app.IntentService#onHandleIntent onHandleIntent()}.

+ +

If you decide to also override other callback methods, such as {@link +android.app.IntentService#onCreate onCreate()}, {@link +android.app.IntentService#onStartCommand onStartCommand()}, or {@link +android.app.IntentService#onDestroy onDestroy()}, be sure to call the super implementation, so +that the {@link android.app.IntentService} can properly handle the life of the worker thread.

+ +

For example, {@link android.app.IntentService#onStartCommand onStartCommand()} must return +the default implementation (which is how the intent gets delivered to {@link +android.app.IntentService#onHandleIntent onHandleIntent()}):

+ +
+@Override
+public int onStartCommand(Intent intent, int flags, int startId) {
+    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+    return super.onStartCommand(intent,flags,startId);
+}
+
+ +

Besides {@link android.app.IntentService#onHandleIntent onHandleIntent()}, the only method +from which you don't need to call the super class is {@link android.app.IntentService#onBind +onBind()} (but you only need to implement that if your service allows binding).

+ +

In the next section, you'll see how the same kind of service is implemented when extending +the base {@link android.app.Service} class, which is a lot more code, but which might be +appropriate if you need to handle simultaneous start requests.

+ + +

Extending the Service class

+ +

As you saw in the previous section, using {@link android.app.IntentService} makes your +implementation of a started service very simple. If, however, you require your service to +perform multi-threading (instead of processing start requests through a work queue), then you +can extend the {@link android.app.Service} class to handle each intent.

+ +

For comparison, the following example code is an implementation of the {@link +android.app.Service} class that performs the exact same work as the example above using {@link +android.app.IntentService}. That is, for each start request, it uses a worker thread to perform the +job and processes only one request at a time.

+ +
+public class HelloService extends Service {
+  private Looper mServiceLooper;
+  private ServiceHandler mServiceHandler;
+
+  // Handler that receives messages from the thread
+  private final class ServiceHandler extends Handler {
+      public ServiceHandler(Looper looper) {
+          super(looper);
+      }
+      @Override
+      public void handleMessage(Message msg) {
+          // Normally we would do some work here, like download a file.
+          // For our sample, we just sleep for 5 seconds.
+          long endTime = System.currentTimeMillis() + 5*1000;
+          while (System.currentTimeMillis() < endTime) {
+              synchronized (this) {
+                  try {
+                      wait(endTime - System.currentTimeMillis());
+                  } catch (Exception e) {
+                  }
+              }
+          }
+          // Stop the service using the startId, so that we don't stop
+          // the service in the middle of handling another job
+          stopSelf(msg.arg1);
+      }
+  }
+
+  @Override
+  public void onCreate() {
+    // Start up the thread running the service.  Note that we create a
+    // separate thread because the service normally runs in the process's
+    // main thread, which we don't want to block.  We also make it
+    // background priority so CPU-intensive work will not disrupt our UI.
+    HandlerThread thread = new HandlerThread("ServiceStartArguments",
+            Process.THREAD_PRIORITY_BACKGROUND);
+    thread.start();
+    
+    // Get the HandlerThread's Looper and use it for our Handler 
+    mServiceLooper = thread.getLooper();
+    mServiceHandler = new ServiceHandler(mServiceLooper);
+  }
+
+  @Override
+  public int onStartCommand(Intent intent, int flags, int startId) {
+      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+
+      // For each start request, send a message to start a job and deliver the
+      // start ID so we know which request we're stopping when we finish the job
+      Message msg = mServiceHandler.obtainMessage();
+      msg.arg1 = startId;
+      mServiceHandler.sendMessage(msg);
+      
+      // If we get killed, after returning from here, restart
+      return START_STICKY;
+  }
+
+  @Override
+  public IBinder onBind(Intent intent) {
+      // We don't provide binding, so return null
+      return null;
+  }
+  
+  @Override
+  public void onDestroy() {
+    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); 
+  }
+}
+
+ +

As you can see, it's a lot more work than using {@link android.app.IntentService}.

+ +

However, because you handle each call to {@link android.app.Service#onStartCommand +onStartCommand()} yourself, you can perform multiple requests simultaneously. That's not what +this example does, but if that's what you want, then you can create a new thread for each +request and run them right away (instead of waiting for the previous request to finish).

+ +

Notice that the {@link android.app.Service#onStartCommand onStartCommand()} method must return an +integer. The integer is a value that describes how the system should continue the service in the +event that the system kills it (as discussed above, the default implementation for {@link +android.app.IntentService} handles this for you, though you are able to modify it). The return value +from {@link android.app.Service#onStartCommand onStartCommand()} must be one of the following +constants:

+ +
+
{@link android.app.Service#START_NOT_STICKY}
+
If the system kills the service after {@link android.app.Service#onStartCommand +onStartCommand()} returns, do not recreate the service, unless there are pending +intents to deliver. This is the safest option to avoid running your service when not necessary +and when your application can simply restart any unfinished jobs.
+
{@link android.app.Service#START_STICKY}
+
If the system kills the service after {@link android.app.Service#onStartCommand +onStartCommand()} returns, recreate the service and call {@link +android.app.Service#onStartCommand onStartCommand()}, but do not redeliver the last intent. +Instead, the system calls {@link android.app.Service#onStartCommand onStartCommand()} with a +null intent, unless there were pending intents to start the service, in which case, +those intents are delivered. This is suitable for media players (or similar services) that are not +executing commands, but running indefinitely and waiting for a job.
+
{@link android.app.Service#START_REDELIVER_INTENT}
+
If the system kills the service after {@link android.app.Service#onStartCommand +onStartCommand()} returns, recreate the service and call {@link +android.app.Service#onStartCommand onStartCommand()} with the last intent that was delivered to the +service. Any pending intents are delivered in turn. This is suitable for services that are +actively performing a job that should be immediately resumed, such as downloading a file.
+
+

For more details about these return values, see the linked reference documentation for each +constant.

+ + + +

Starting a Service

+ +

You can start a service from an activity or other application component by passing an +{@link android.content.Intent} (specifying the service to start) to {@link +android.content.Context#startService startService()}. The Android system calls the service's {@link +android.app.Service#onStartCommand onStartCommand()} method and passes it the {@link +android.content.Intent}. (You should never call {@link android.app.Service#onStartCommand +onStartCommand()} directly.)

+ +

For example, an activity can start the example service in the previous section ({@code +HelloSevice}) using an explicit intent with {@link android.content.Context#startService +startService()}:

+ +
+Intent intent = new Intent(this, HelloService.class);
+startService(intent);
+
+ +

The {@link android.content.Context#startService startService()} method returns immediately and +the Android system calls the service's {@link android.app.Service#onStartCommand +onStartCommand()} method. If the service is not already running, the system first calls {@link +android.app.Service#onCreate onCreate()}, then calls {@link android.app.Service#onStartCommand +onStartCommand()}.

+ +

If the service does not also provide binding, the intent delivered with {@link +android.content.Context#startService startService()} is the only mode of communication between the +application component and the service. However, if you want the service to send a result back, then +the client that starts the service can create a {@link android.app.PendingIntent} for a broadcast +(with {@link android.app.PendingIntent#getBroadcast getBroadcast()}) and deliver it to the service +in the {@link android.content.Intent} that starts the service. The service can then use the +broadcast to deliver a result.

+ +

Multiple requests to start the service result in multiple corresponding calls to the service's +{@link android.app.Service#onStartCommand onStartCommand()}. However, only one request to stop +the service (with {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}) is required to stop it.

+ + +

Stopping a service

+ +

A started service must manage its own lifecycle. That is, the system does not stop or +destroy the service unless it must recover system memory and the service +continues to run after {@link android.app.Service#onStartCommand onStartCommand()} returns. So, +the service must stop itself by calling {@link android.app.Service#stopSelf stopSelf()} or another +component can stop it by calling {@link android.content.Context#stopService stopService()}.

+ +

Once requested to stop with {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}, the system destroys the service as soon as +possible.

+ +

However, if your service handles multiple requests to {@link +android.app.Service#onStartCommand onStartCommand()} concurrently, then you shouldn't stop the +service when you're done processing a start request, because you might have since received a new +start request (stopping at the end of the first request would terminate the second one). To avoid +this problem, you can use {@link android.app.Service#stopSelf(int)} to ensure that your request to +stop the service is always based on the most recent start request. That is, when you call {@link +android.app.Service#stopSelf(int)}, you pass the ID of the start request (the startId +delivered to {@link android.app.Service#onStartCommand onStartCommand()}) to which your stop request +corresponds. Then if the service received a new start request before you were able to call {@link +android.app.Service#stopSelf(int)}, then the ID will not match and the service will not stop.

+ +

Caution: It's important that your application stops its services +when it's done working, to avoid wasting system resources and consuming battery power. If necessary, +other components can stop the service by calling {@link +android.content.Context#stopService stopService()}. Even if you enable binding for the service, +you must always stop the service yourself if it ever received a call to {@link +android.app.Service#onStartCommand onStartCommand()}.

+ +

For more information about the lifecycle of a service, see the section below about Managing the Lifecycle of a Service.

+ + + +

Creating a Bound Service

+ +

A bound service is one that allows application components to bind to it by calling {@link +android.content.Context#bindService bindService()} in order to create a long-standing connection +(and generally does not allow components to start it by calling {@link +android.content.Context#startService startService()}).

+ +

You should create a bound service when you want to interact with the service from activities +and other components in your application or to expose some of your application's functionality to +other applications, through interprocess communication (IPC).

+ +

To create a bound service, you must implement the {@link +android.app.Service#onBind onBind()} callback method to return an {@link android.os.IBinder} that +defines the interface for communication with the service. Other application components can then call +{@link android.content.Context#bindService bindService()} to retrieve the interface and +begin calling methods on the service. The service lives only to serve the application component that +is bound to it, so when there are no components bound to the service, the system destroys it +(you do not need to stop a bound service in the way you must when the service is started +through {@link android.app.Service#onStartCommand onStartCommand()}).

+ +

To create a bound service, the first thing you must do is define the interface that specifies +how a client can communicate with the service. This interface between the service +and a client must be an implementation of {@link android.os.IBinder} and is what your service must +return from the {@link android.app.Service#onBind +onBind()} callback method. Once the client receives the {@link android.os.IBinder}, it can begin +interacting with the service through that interface.

+ +

Multiple clients can bind to the service at once. When a client is done interacting with the +service, it calls {@link android.content.Context#unbindService unbindService()} to unbind. Once +there are no clients bound to the service, the system destroys the service.

+ +

There are multiple ways to implement a bound service and the implementation is more +complicated than a started service, so the bound service discussion appears in a separate +document about Bound Services.

+ + + +

Sending Notifications to the User

+ +

Once running, a service can notify the user of events using Toast Notifications or Status Bar Notifications.

+ +

A toast notification is a message that appears on the surface of the current window for a +moment then disappears, while a status bar notification provides an icon in the status bar with a +message, which the user can select in order to take an action (such as start an activity).

+ +

Usually, a status bar notification is the best technique when some background work has completed +(such as a file completed +downloading) and the user can now act on it. When the user selects the notification from the +expanded view, the notification can start an activity (such as to view the downloaded file).

+ +

See the Toast Notifications or Status Bar Notifications +developer guides for more information.

+ + + +

Running a Service in the Foreground

+ +

A foreground service is a service that's considered to be something the +user is actively aware of and thus not a candidate for the system to kill when low on memory. A +foreground service must provide a notification for the status bar, which is placed under the +"Ongoing" heading, which means that the notification cannot be dismissed unless the service is +either stopped or removed from the foreground.

+ +

For example, a music player that plays music from a service should be set to run in the +foreground, because the user it explicitly aware +of its operation. The notification in the status bar might indicate the current song and allow +the user to launch an activity to interact with the music player.

+ +

To request that your service run in the foreground, call {@link +android.app.Service#startForeground startForeground()}. This method takes two parameters: an integer +that uniquely identifies the notification and the {@link +android.app.Notification} for the status bar. For example:

+ +
+Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
+        System.currentTimeMillis());
+Intent notificationIntent = new Intent(this, ExampleActivity.class);
+PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
+notification.setLatestEventInfo(this, getText(R.string.notification_title),
+        getText(R.string.notification_message), pendingIntent);
+startForeground(ONGOING_NOTIFICATION, notification);
+
+ + +

To remove the service from the foreground, call {@link +android.app.Service#stopForeground stopForeground()}. This method takes a boolean, indicating +whether to remove the status bar notification as well. This method does not stop the +service. However, if you stop the service while it's still running in the foreground, then the +notification is also removed.

+ +

Note: The methods {@link +android.app.Service#startForeground startForeground()} and {@link +android.app.Service#stopForeground stopForeground()} were introduced in Android 2.0 (API Level +5). In order to run your service in the foreground on older versions of the platform, you must +use the previous {@code setForeground()} method—see the {@link +android.app.Service#startForeground startForeground()} documentation for information about how +to provide backward compatibility.

+ +

For more information about notifications, see Creating Status Bar +Notifications.

+ + + +

Managing the Lifecycle of a Service

+ +

The lifecycle of a service is much simpler than that of an activity. However, it's even more important +that you pay close attention to how your service is created and destroyed, because a service +can run in the background without the user being aware.

+ +

The service lifecycle—from when it's created to when it's destroyed—can follow two +different paths:

+ + + +

These two paths are not entirely separate. That is, you can bind to a service that was already +started with {@link android.content.Context#startService startService()}. For example, a background +music service could be started by calling {@link android.content.Context#startService +startService()} with an {@link android.content.Intent} that identifies the music to play. Later, +possibly when the user wants to exercise some control over the player or get information about the +current song, an activity can bind to the service by calling {@link +android.content.Context#bindService bindService()}. In cases like this, {@link +android.content.Context#stopService stopService()} or {@link android.app.Service#stopSelf +stopSelf()} does not actually stop the service until all clients unbind.

+ + +

Implementing the lifecycle callbacks

+ +

Like an activity, a service has lifecycle callback methods that you can implement to monitor +changes in the service's state and perform work at the appropriate times. The following skeleton +service demonstrates each of the lifecycle methods:

+ + +
+ +

Figure 2. The service lifecycle. The diagram on the left +shows the lifecycle when the service is created with {@link android.content.Context#startService +startService()} and the diagram on the right shows the lifecycle when the service is created +with {@link android.content.Context#bindService bindService()}.

+
+ +
+public class ExampleService extends Service {
+    int mStartMode;       // indicates how to behave if the service is killed
+    IBinder mBinder;      // interface for clients that bind
+    boolean mAllowRebind; // indicates whether onRebind should be used
+
+    @Override
+    public void {@link android.app.Service#onCreate onCreate}() {
+        // The service is being created
+    }
+    @Override
+    public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) {
+        // The service is starting, due to a call to {@link android.content.Context#startService startService()}
+        return mStartMode;
+    }
+    @Override
+    public IBinder {@link android.app.Service#onBind onBind}(Intent intent) {
+        // A client is binding to the service with {@link android.content.Context#bindService bindService()}
+        return mBinder;
+    }
+    @Override
+    public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) {
+        // All clients have unbound with {@link android.content.Context#unbindService unbindService()}
+        return mAllowRebind;
+    }
+    @Override
+    public void {@link android.app.Service#onRebind onRebind}(Intent intent) {
+        // A client is binding to the service with {@link android.content.Context#bindService bindService()},
+        // after onUnbind() has already been called
+    }
+    @Override
+    public void {@link android.app.Service#onDestroy onDestroy}() {
+        // The service is no longer used and is being destroyed
+    }
+}
+
+ +

Note: Unlike the activity lifecycle callback methods, you are +not required to call the superclass implementation of these callback methods.

+ +

By implementing these methods, you can monitor two nested loops of the service's lifecycle:

+ + + +

Note: Although a started service is stopped by a call to +either {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}, there is not a respective callback for the +service (there's no {@code onStop()} callback). So, unless the service is bound to a client, +the system destroys it when the service is stopped—{@link +android.app.Service#onDestroy onDestroy()} is the only callback received.

+ +

Figure 2 illustrates the typical callback methods for a service. Although the figure separates +services that are created by {@link android.content.Context#startService startService()} from those +created by {@link android.content.Context#bindService bindService()}, keep +in mind that any service, no matter how it's started, can potentially allow clients to bind to it. +So, a service that was initially started with {@link android.app.Service#onStartCommand +onStartCommand()} (by a client calling {@link android.content.Context#startService startService()}) +can still receive a call to {@link android.app.Service#onBind onBind()} (when a client calls +{@link android.content.Context#bindService bindService()}).

+ +

For more information about creating a service that provides binding, see the Bound Services document, +which includes more information about the {@link android.app.Service#onRebind onRebind()} +callback method in the section about Managing the Lifecycle of +a Bound Service.

+ + + +

Beginner's Path

+ +

To learn how to query data from the system or other applications (such as contacts or media +stored on the device), continue with the Content Providers +document.

diff --git a/docs/html/images/fundamentals/service_binding_tree_lifecycle.png b/docs/html/images/fundamentals/service_binding_tree_lifecycle.png new file mode 100644 index 0000000000000..46d2df50e85a3 Binary files /dev/null and b/docs/html/images/fundamentals/service_binding_tree_lifecycle.png differ diff --git a/docs/html/images/service_lifecycle.png b/docs/html/images/service_lifecycle.png index 0748db280183e..f9602f84a93a7 100644 Binary files a/docs/html/images/service_lifecycle.png and b/docs/html/images/service_lifecycle.png differ