The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.
As noted previously, Android services are for long-running processes that may need to keep running even when decoupled from any activity. Examples include playing music even if the “player” activity is destroyed, polling the Internet for RSS/Atom feed updates, and maintaining an online chat connection even if the chat client loses focus due to an incoming phone call.
Services are created when manually started (via an API call) or when some activity tries connecting to the service via inter-process communication (IPC). Services will live until specifically shut down or until Android is desperate for RAM and terminates the process. Running for a long time has its costs, though, so services need to be careful not to use too much CPU or keep radios active too much of the time, lest the service cause the device’s battery to get used up too quickly.
This chapter outlines the basic theory behind creating and consuming services, including a look at the “command pattern” for services.
Services are a “Swiss Army knife” for a wide range of functions that do not require direct access to an activity’s user interface, such as:
Even things like home screen app widgets often involve a service to assist with long-running work.
The primary role of a service is as a flag to the operating system, letting it know that your process is still doing work, despite the fact that it is in the background. This makes it somewhat less likely that Android will terminate your process due to low memory conditions.
Many applications will not need any services. Very few applications will need more than one. However, the service is a powerful tool for an Android developer’s toolbox and is a subject with which any qualified Android developer should be familiar.
Creating a service implementation shares many characteristics with building an activity. You inherit from an Android-supplied base class, override some lifecycle methods, and hook the service into the system via the manifest.
Just as an activity in your application extends either
Activity or an
Activity subclass, a service in your application extends
Service or an Android-supplied
Service subclass. The most common
Service subclass is
IntentService, used primarily for the command pattern,
described later in this chapter. That being said, many services
Just as activities have
onPause() and kin,
Service implementations have their own lifecycle methods, such as:
onCreate(), which, as with activities, is called when the service is created, by any means
onStartCommand(), which is called each time the service is sent a command via
onBind(), which is called whenever a client binds to the service via
onDestroy()which is called as the service is being shut down
As with activities, services initialize whatever they need in
clean up those items in
onDestroy(). And, as with activities, the
onDestroy() method of a service might not be called, if Android terminates
the entire application process, such as for emergency RAM reclamation.
onBind() lifecycle methods will be implemented
based on your choice of communicating to the client, as will be explained
later in this chapter.
Service is an
abstract class and
onBind() is an
method, so even if you are not using
bindService(), you will need to implement
onBind() in order to successfully compile. A common approach here is to
onBind() simply return
Finally, you need to add the service to your
AndroidManifest.xml file, for it
to be recognized as an available service for use. That is simply a matter of
<service> element as a child of the
application element, providing
android:name to reference your service class.
Since the service class is in the same Java namespace as everything else in
this application, we can use the shorthand (e.g.,
"PlayerService") to reference our class.
For example, here is a manifest showing the
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.commonsware.android.fakeplayer" android:versionCode="1" android:versionName="1.0"> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light.DarkActionBar"> <activity android:name="FakePlayer" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <service android:name="PlayerService"/> </application> </manifest>
The preview of this section was eaten by a grue.
The preview of this section is out seeking fame and fortune as the Dread Pirate Roberts.
The preview of this section took that left turn at Albuquerque.
The preview of this section will not appear here for a while, due to a time machine mishap.
The preview of this section was fed to a gremlin, after midnight.