cherrypick Change-Id: I1365c6c45f8e1f75ee4afbc52c32778d21b97be4 from master

docs: Rewrite of App Fundamentals.. Part 2.
This introduces three new docs:

Services:
  Provides an introduction to using services and describes the
  service lifecycle (previously in the "Component Lifecycles" section
  of the fundamentals.jd document)
Bound Services:
  A guide for services that offer binding.
AIDL:
  A doc about using AIDL (primarily for creating a service interface)

Also includes edits to IntentService javadocs to clarify
different behaviors for some callback methods

Includes a new version of the services lifecycle diagram
and an additional diagram for determining onRebind()

These files are orphaned for now---they're not linked in the sidenav,
until I get the last couple documents submitted for the app fundamentals.

Change-Id: I7fb0a8faff1f18b7d6b9a7b59f66f55a1b6168f1
This commit is contained in:
Scott Main
2010-10-04 18:30:46 -07:00
parent 4c3b788ec4
commit 2150553dc3
6 changed files with 1935 additions and 0 deletions

View File

@@ -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)}.

View File

@@ -0,0 +1,387 @@
page.title=Android Interface Definition Language (AIDL)
@jd:body
<p>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.</p>
<p class="note"><strong>Note:</strong> 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 <a href="Binder">implementing a
Binder</a> or, if you want to perform IPC, but do not need to handle multithreading, then you
should implement your interface <a href="#Messenger">using a Messenger</a>.</p>
<p>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:</p>
<ul>
<li>Calls from the local process are executed in the same thread that is making the call. If this is
your main UI thread, that thread will continue executing into the aidl interface. If it is another
thread, that is one that will be executing your code. Thus if only local threads are accessing the
interface, you can completely control which threads are executing in it (but if that is the case,
why are you defining an aidl interface at all?).</li>
<li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of
your own process. You must be prepared for incoming calls from unknown threads, with multiple calls
happening at the same time. In other words, an implementation of an aidl interface must be
completely thread-safe.</li>
<li>The "oneway" keyword modifies the behavior of remote calls. When used, a remote call will not
block until its call completes; it simply sends the transaction data and immediately returns. The
implementation of the interface will eventually receive this as a regular call from the {@link
android.os.Binder} thread pool as a normal remote call. If "oneway" is used with a local call,
there is no impact and the call is still synchronous.</li>
</ul>
<h2 id="Defining">Defining an AIDL Interface</h2>
<p>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.</p>
<p>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&mdash;you
must implement the interface in your service.</p>
<p>To create a bounded service using AIDL, follow these steps:</p>
<ol>
<li><a href="#CreateAidl">Create the .aidl file</a>
<p>This file defines the programming interface with method signatures.</p>
</li>
<li><a href="#ImplementTheInterface">Implement the interface</a>
<p>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.</p>
</li>
<li><a href="#ExposeTheInterface">Expose the interface to clients</a>
<p>Implement a {@link android.app.Service Service} and override {@link
android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
class.</p>
</li>
</ol>
<p class="caution"><strong>Caution:</strong> 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.</p>
<h3 id="CreateAidl">1. Create the .aidl file</h3>
<p>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.</p>
<p>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.</p>
<p>By default, AIDL supports the following data types:</p>
<ul>
<li>All primitive types in the Java programming language ({@code int}, {@code long}, {@code
char}, {@code boolean}, etc.)</li>
<li>{@link java.lang.String}</li>
<li>{@link java.lang.CharSequence}</li>
<li>{@link java.util.List}
<p>All elements in the {@link java.util.List} must be one of the supported data types in this
list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
java.util.List} may optionally be used as a "generic" class (e.g. <code>List&lt;String&gt;</code>).
The actual concrete class that the other side will receive will always be an {@link
java.util.ArrayList}, although the method will be generated to use the {@link
java.util.List} interface.</p>
</li>
<li>{@link java.util.Map}
<p>All elements in the {@link java.util.Map} must be one of the supported data types in this
list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
(such as those of the form
{@code Map&lt;String,Integer&gt;} are not supported. The actual concrete class that the other side
will receive will always be a {@link java.util.HashMap}, although the method will be generated to
use the {@link java.util.Map} interface.</p>
</li>
</ul>
<p>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.</p>
<p>When defining methods for your service interface, be aware that:</p>
<ul>
<li>Methods can take zero or more parameters, and return a value or void.</li>
<li>All non-primitive parameters require a directional tag indicating which way the data will go.
Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below).
<p>Primitives are <code>in</code> by default, and cannot be otherwise.</p>
<p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly
needed, because marshalling parameters is expensive.</p></li>
<li>All code comments included in the {@code .aidl} file are included in the generated {@link
android.os.IBinder} interface (except for comments before the import and package
statements).</li>
</ul>
<p>Here is an example {@code .aidl} file:</p>
<pre>
// 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);
}
</pre>
<p>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}).</p>
<p>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&mdash;you should build your project with <code>ant debug</code> (or <code>ant
release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
link against the generated class.</p>
<h3 id="ImplementTheInterface">2. Implement the interface</h3>
<p>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.</p>
<p class="note"><strong>Note:</strong> {@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 <a href="#calling">Calling an IPC
Method</a> for more details on how to make this cast.</p></p>
<p>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.</p>
<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
<pre>
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
}
};
</pre>
<p>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.</p>
<p>There are a few rules you should be aware of when implementing your AIDL interface: </p>
<ul>
<li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think
about multithreading from the start and properly build your service to be thread-safe.</li>
<li>By default, RPC calls are synchronous. If you know that the service takes more than a few
milliseconds to complete a request, you should not call it from the activity's main thread, because
it might hang the application (Android might display an &quot;Application is Not Responding&quot;
dialog)&mdash;you should usually call them from a separate thread in the client. </li>
<li>No exceptions that you throw are sent back to the caller.</li>
<li>Only methods are supported; you cannot expose static fields in AIDL.</li>
</ul>
<h3 id="ExposeTheInterface">3. Expose the interface to clients</h3>
<p>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. </p>
<pre>
public class RemoteService extends Service {
&#64;Override
public void onCreate() {
super.onCreate();
}
&#64;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
}
};
}
</pre>
<p>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.</p>
<p>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&mdash;providing the client access to the AIDL methods).</p>
<p>When the client receives the {@link android.os.IBinder} in the {@link
android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
<code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned
parameter to <code><em>YourServiceInterface</em></code> type. For example:</p>
<pre>
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");
}
};
</pre>
<p>For more sample code, 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="PassingObjects">Passing Objects over IPC</h2>
<p>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.</p>
<p>There are five parts to making a class support the {@link android.os.Parcelable} protocol:</b>
<ol>
<li>Make your class implement the {@link android.os.Parcelable} interface.</li>
<li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the
current state of the object and writes it to a {@link android.os.Parcel}.</li>
<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
<li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the
{@code Rect.aidl} file, below).
<p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your
build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li>
</ol>
<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall
your objects.</p>
<p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's
parcelable:</p>
<pre>
package android.graphics;
// Declare Rect so AIDL can find it and knows that it implements
// the parcelable protocol.
parcelable Rect;
</pre>
<p>And here is an example of how the {@link android.graphics.Rect} class implements the
{@link android.os.Parcelable} protocol.</p>
<pre>
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&lt;Rect&gt; CREATOR = new
Parcelable.Creator&lt;Rect&gt;() {
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();
}
}
</pre>
<p>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.</p>
<p class="warning"><strong>Warning:</strong> 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 <a
href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
information about how to keep your application secure from malware.</p>

View File

@@ -0,0 +1,675 @@
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/topics/fundamentals/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/topics/fundamentals/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/topics/fundamentals/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/topics/advanced/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;
}
}
&#64;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;
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
&#64;Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
&#64;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() {
&#64;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;
}
&#64;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/topics/advanced/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}&mdash;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 {
&#64;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.
*/
&#64;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();
}
}
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
&#64;Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
&#64;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&mdash;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
this 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/topics/fundamentals/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>
<div class="figure" style="width:588px">
<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>
</div>
<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&mdash;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>
<p>For more information about the lifecycle of an started service, see the <a
href="{@docRoot}guide/topics/fundamentals/services.html#Lifecycle">Services</a> document.</p>

View File

@@ -0,0 +1,860 @@
page.title=Services
parent.title=Application Fundamentals
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<ol id="qv">
<h2>Quickview</h2>
<ul>
<li>A service can run in the background to perform work even while the user is in a different
application</li>
<li>A service can allow other components to bind to it, in order to interact with it and
perform interprocess communication</li>
<li>A service runs in the main thread of the application that hosts it, by default</li>
</ul>
<h2>In this document</h2>
<ol>
<li><a href="#Basics">The Basics</a></li>
<ol>
<li><a href="#Declaring">Declaring a service in the manifest</a></li>
</ol>
<li><a href="#CreatingAService">Creating a Started Service</a>
<ol>
<li><a href="#ExtendingIntentService">Extending the IntentService class</a></li>
<li><a href="#ExtendingService">Extending the Service class</a></li>
<li><a href="#StartingAService">Starting a service</a></li>
<li><a href="#Stopping">Stopping a service</a></li>
</ol>
</li>
<li><a href="#CreatingBoundService">Creating a Bound Service</a></li>
<li><a href="#Notifications">Sending Notifications to the User</a></li>
<li><a href="#Foreground">Running a Service in the Foreground</a></li>
<li><a href="#Lifecycle">Managing the Lifecycle of a Service</a>
<ol>
<li><a href="#LifecycleCallbacks">Implementing the lifecycle callbacks</a></li>
</ol>
</li>
</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.app.Service}</li>
<li>{@link android.app.IntentService}</li>
</ol>
<h2>Samples</h2>
<ol>
<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code
ServiceStartArguments}</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/topics/fundamentals/bound-services.html">Bound Services</a></li>
</ol>
</div>
<p>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.</p>
<p>A service can essentially take two forms:</p>
<dl>
<dt>Started</dt>
<dd>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.</dd>
<dt>Bound</dt>
<dd>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.</dd>
</dl>
<p>Although this documentation generally discusses these two types of services separately, your
service can work both ways&mdash;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.</p>
<p>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&mdash;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 <a href="#Declaring">Declaring the service in the
manifest</a>.</p>
<p class="caution"><strong>Caution:</strong> A service runs in the
main thread of its hosting process&mdash;the service does <strong>not</strong> create its own thread
and does <strong>not</strong> 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.</p>
<h2 id="Basics">The Basics</h2>
<div class="sidebox-wrapper">
<div class="sidebox">
<h3>Should you use a service or a thread?</h3>
<p>A service is simply a component that can run in the background even when the user is not
interacting with your application. Thus, you should create a service only if that is what you
need.</p>
<p>If you need to perform work outside your main thread, but only while the user is interacting
with your application, then you should probably instead create a new thread and not a service. For
example, if you want to play some music, but only while your activity is running, you might create
a thread in {@link android.app.Activity#onCreate onCreate()}, start running it in {@link
android.app.Activity#onStart onStart()}, then stop it in {@link android.app.Activity#onStop
onStop()}. Also consider using {@link android.os.AsyncTask} or {@link android.os.HandlerThread},
instead of the traditional {@link java.lang.Thread} class. See the <a
href="{@docRoot}guide/topics/fundamentals/processes-and-threading.html#Threads">Processes and
Threading</a> document for more information about threads.</p>
<p>Remember that if you do use a service, it still runs in your application's main thread by
default, so you should still create a new thread within the service if it performs intensive or
blocking operations.</p>
</div>
</div>
<p>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:</p>
<dl>
<dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt>
<dd>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.)</dd>
<dt>{@link android.app.Service#onBind onBind()}</dt>
<dd>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.</dd>
<dt>{@link android.app.Service#onCreate()}</dt>
<dd>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.</dd>
<dt>{@link android.app.Service#onDestroy()}</dt>
<dd>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.</dd>
</dl>
<p>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()}.</p>
<p>If a component calls
{@link android.content.Context#bindService bindService()} to create the service (and {@link
android.app.Service#onStartCommand onStartCommand()} is <em>not</em> 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.</p>
<p>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 <a
href="#Foreground">run in the foreground</a> (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&mdash;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 <a
href="{@docRoot}guide/topics/fundamentals/processes-and-threading.html">Processes and Threading</a>
document.</p>
<p>In the following sections, you'll see how you can create each type of service and how to use
it from other application components.</p>
<h3 id="Declaring">Declaring a service in the manifest</h3>
<p>Like activities (and other components), you must declare all services in your application's
manifest file.</p>
<p>To decalare your service, add a <a
href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> element
as a child of the <a
href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
element. For example:</p>
<pre>
&lt;manifest ... &gt;
...
&lt;application ... &gt;
&lt;service android:name=".ExampleService" /&gt;
...
&lt;/application&gt;
&lt;/manifest&gt;
</pre>
<p>There are other attributes you can include in the <a
href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> element to
define properties such as permissions required to start the service and the process in
which the service should run. See the <a
href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> element
reference for more information.</p>
<p>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()}.</p>
<p>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 <a href="#StartingAService">starting a service</a> is discussed below.</p>
<p>Additionally, you can ensure that your service is private to your application only if
you include the <a
href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a>
attribute and set it to {@code "false"}. This is effective even if your service supplies intent
filters.</p>
<p>For more information about creating intent filters for your service, see the <a
href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
document.</p>
<h2 id="CreatingStartedService">Creating a Started Service</h2>
<div class="sidebox-wrapper">
<div class="sidebox">
<h2>Targeting Android 1.6 or lower</h2>
<p>If you're building an application for Android 1.6 or lower, you need
to implement {@link android.app.Service#onStart onStart()}, instead of {@link
android.app.Service#onStartCommand onStartCommand()} (in Android 2.0,
{@link android.app.Service#onStart onStart()} was deprecated in favor of {@link
android.app.Service#onStartCommand onStartCommand()}).</p>
<p>For more information about providing compatibility with versions of Android older than 2.0, see
the {@link android.app.Service#onStartCommand onStartCommand()} documentation.</p>
</div>
</div>
<p>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.</p>
<p>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()}.</p>
<p>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.</p>
<p>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.</p>
<p class="caution"><strong>Caution:</strong> 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.</p>
<p>Traditionally, there are two classes you can extend to create a started service:</p>
<dl>
<dt>{@link android.app.Service}</dt>
<dd>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.</dd>
<dt>{@link android.app.IntentService}</dt>
<dd>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.</dd>
</dl>
<p>The following sections describe how you can implement your service using either one for these
classes.</p>
<h3 id="ExtendingIntentService">Extending the IntentService class</h3>
<p>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.</p>
<p>The {@link android.app.IntentService} does the following:</p>
<ul>
<li>Creates a default worker thread that executes all intents delivered to {@link
android.app.Service#onStartCommand onStartCommand()} separate from your application's main
thread.</li>
<li>Creates a work queue that passes one intent at a time to your {@link
android.app.IntentService#onHandleIntent onHandleIntent()} implementation, so you never have to
worry about multi-threading.</li>
<li>Stops the service after all start requests have been handled, so you never have to call
{@link android.app.Service#stopSelf}.</li>
<li>Provides default implementation of {@link android.app.IntentService#onBind onBind()} that
returns null.</li>
<li>Provides a default implementation of {@link android.app.IntentService#onStartCommand
onStartCommand()} that sends the intent to the work queue and then to your {@link
android.app.IntentService#onHandleIntent onHandleIntent()} implementation.</li>
</ul>
<p>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.)</p>
<p>Here's an example implementation of {@link android.app.IntentService}:</p>
<pre>
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.
*/
&#64;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() &lt; endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
}
}
</pre>
<p>That's all you need: a constructor and an implementation of {@link
android.app.IntentService#onHandleIntent onHandleIntent()}.</p>
<p>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.</p>
<p>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()}):</p>
<pre>
&#64;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);
}
</pre>
<p>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).</p>
<p>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.</p>
<h3 id="ExtendingService">Extending the Service class</h3>
<p>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.</p>
<p>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.</p>
<pre>
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);
}
&#64;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() &lt; 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);
}
}
&#64;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);
}
&#64;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;
}
&#64;Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
&#64;Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
</pre>
<p>As you can see, it's a lot more work than using {@link android.app.IntentService}.</p>
<p>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).</p>
<p>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:</p>
<dl>
<dt>{@link android.app.Service#START_NOT_STICKY}</dt>
<dd>If the system kills the service after {@link android.app.Service#onStartCommand
onStartCommand()} returns, <em>do not</em> 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.</dd>
<dt>{@link android.app.Service#START_STICKY}</dt>
<dd>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 <em>do not</em> 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.</dd>
<dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt>
<dd>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.</dd>
</dl>
<p>For more details about these return values, see the linked reference documentation for each
constant.</p>
<h3 id="StartingAService">Starting a Service</h3>
<p>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.)</p>
<p>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()}:</p>
<pre>
Intent intent = new Intent(this, HelloService.class);
startService(intent);
</pre>
<p>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()}.</p>
<p>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.</p>
<p>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.</p>
<h3 id="Stopping">Stopping a service</h3>
<p>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()}.</p>
<p>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.</p>
<p>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 <code>startId</code>
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.</p>
<p class="caution"><strong>Caution:</strong> 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()}.</p>
<p>For more information about the lifecycle of a service, see the section below about <a
href="#Lifecycle">Managing the Lifecycle of a Service</a>.</p>
<h2 id="CreatingBoundService">Creating a Bound Service</h2>
<p>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 <em>start</em> it by calling {@link
android.content.Context#startService startService()}).</p>
<p>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).</p>
<p>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 <em>not</em> need to stop a bound service in the way you must when the service is started
through {@link android.app.Service#onStartCommand onStartCommand()}).</p>
<p>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.</p>
<p>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.</p>
<p>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 <a
href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a>.</p>
<h2 id="Notifications">Sending Notifications to the User</h2>
<p>Once running, a service can notify the user of events using <a
href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Toast Notifications</a> or <a
href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>.</p>
<p>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).</p>
<p>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).</p>
<p>See the <a
href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Toast Notifications</a> or <a
href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
developer guides for more information.</p>
<h2 id="Foreground">Running a Service in the Foreground</h2>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<pre>
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);
</pre>
<p>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 <em>not</em> stop the
service. However, if you stop the service while it's still running in the foreground, then the
notification is also removed.</p>
<p class="note"><strong>Note:</strong> 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&mdash;see the {@link
android.app.Service#startForeground startForeground()} documentation for information about how
to provide backward compatibility.</p>
<p>For more information about notifications, see <a
href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status Bar
Notifications</a>.</p>
<h2 id="Lifecycle">Managing the Lifecycle of a Service</h2>
<p>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.</p>
<p>The service lifecycle&mdash;from when it's created to when it's destroyed&mdash;can follow two
different paths:</p>
<ul>
<li>A started service
<p>The service is created when another component calls {@link
android.content.Context#startService startService()}. The service then runs indefinitely and must
stop itself by calling {@link
android.app.Service#stopSelf() stopSelf()}. Another component can also stop the
service by calling {@link android.content.Context#stopService
stopService()}. When the service is stopped, the system destroys it..</p></li>
<li>A bound service
<p>The service is created when another component (a client) calls {@link
android.content.Context#bindService bindService()}. The client then communicates with the service
through an {@link android.os.IBinder} interface. The client can close the connection by calling
{@link android.content.Context#unbindService unbindService()}. Multiple clients can bind to
the same service and when all of them unbind, the system destroys the service. (The service
does <em>not</em> need to stop itself.)</p></li>
</ul>
<p>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. </p>
<h3 id="LifecycleCallbacks">Implementing the lifecycle callbacks</h3>
<p>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:</p>
<div class="figure" style="width:432px">
<img src="{@docRoot}images/service_lifecycle.png" alt="" />
<p class="img-caption"><strong>Figure 2.</strong> 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()}.</p>
</div>
<pre>
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
&#64;Override
public void {@link android.app.Service#onCreate onCreate}() {
// The service is being created
}
&#64;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 <em>mStartMode</em>;
}
&#64;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 <em>mBinder</em>;
}
&#64;Override
public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) {
// All clients have unbound with {@link android.content.Context#unbindService unbindService()}
return <em>mAllowRebind</em>;
}
&#64;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
}
&#64;Override
public void {@link android.app.Service#onDestroy onDestroy}() {
// The service is no longer used and is being destroyed
}
}
</pre>
<p class="note"><strong>Note:</strong> Unlike the activity lifecycle callback methods, you are
<em>not</em> required to call the superclass implementation of these callback methods.</p>
<p>By implementing these methods, you can monitor two nested loops of the service's lifecycle: </p>
<ul>
<li>The <strong>entire lifetime</strong> of a service happens between the time {@link
android.app.Service#onCreate onCreate()} is called and the time {@link
android.app.Service#onDestroy} returns. Like an activity, a service does its initial setup in
{@link android.app.Service#onCreate onCreate()} and releases all remaining resources in {@link
android.app.Service#onDestroy onDestroy()}. For example, a
music playback service could create the thread where the music will be played in {@link
android.app.Service#onCreate onCreate()}, then stop the thread in {@link
android.app.Service#onDestroy onDestroy()}.
<p>The {@link android.app.Service#onCreate onCreate()} and {@link android.app.Service#onDestroy
onDestroy()} methods are called for all services, whether
they're created by {@link android.content.Context#startService startService()} or {@link
android.content.Context#bindService bindService()}.</p></li>
<li>The <strong>active lifetime</strong> of a service begins with a call to either {@link
android.app.Service#onStartCommand onStartCommand()} or {@link android.app.Service#onBind onBind()}.
Each method is handed the {@link
android.content.Intent} that was passed to either {@link android.content.Context#startService
startService()} or {@link android.content.Context#bindService bindService()}, respectively.
<p>If the service is started, the active lifetime ends the same time that the entire lifetime
ends (the service is still active even after {@link android.app.Service#onStartCommand
onStartCommand()} returns). If the service is bound, the active lifetime ends when {@link
android.app.Service#onUnbind onUnbind()} returns.</p>
</li>
</ul>
<p class="note"><strong>Note:</strong> 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&mdash;{@link
android.app.Service#onDestroy onDestroy()} is the only callback received.</p>
<p>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()}).</p>
<p>For more information about creating a service that provides binding, see the <a
href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a> document,
which includes more information about the {@link android.app.Service#onRebind onRebind()}
callback method in the section about <a
href="{@docRoot}guide/topics/fundamentals/bound-services.html#Lifecycle">Managing the Lifecycle of
a Bound Service</a>.</p>
<h2>Beginner's Path</h2>
<p>To learn how to query data from the system or other applications (such as contacts or media
stored on the device), continue with the <b><a
href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b>
document.</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 74 KiB