Working with Services
Determining When to Use Services
A service within the Android Software Development Kit (SDK) can mean one of two things. First, a service can mean a background process, performing some useful operation at regular intervals. Second, a service can be an interface for a remote object, called from within your application. In both cases, the service object extends the Service class from the Android SDK, and it can be a stand-alone component or part of an application with a complete user interface. Certainly, not all applications require or use services. However, you might want to consider a service if your application meets certain criteria, such as the following: n The application performs lengthy or resource-intensive processing that does not require input from the user. n The application must perform certain functions routinely, or at regular intervals, such as uploading or downloading fresh content or logging the current location. n The application performs a lengthy operation that, if cancelled because the application exits, would be wasteful to restart.An example of this is downloading large files. n The application needs to expose and provide data or information services (think web services) to other Android applications without the need of a user interface. Working with Services 438 Chapter 21 Working with Services Note Android Cloud to Device Messaging (C2DM) is a service that was introduced in Android 2.2. This service provides developers with the ability to initiate application events remotely, effectively waking up the application when needed instead of requiring each application to implement a background service itself (improving battery life). Instead, the C2DM service runs on the device and is shared by interested applications. Developers send messages from remote servers through to the device’s C2DM service, which delivers the message to the target application. For devices running 2.2 and higher, consider if the C2DM solution is more appropriate for your application than services. For more information about Cloud to Device Messaging, see the Google Project website: http://code.google.com/android/c2dm/.
Understanding the Service Lifecycle
Before we get into the details of how to create a service, let’s look at how services interact with the Android operating system. First, it should be noted that a service implementation must be registered in that application’s manifest file using the tag.The service implementation might also define and enforce any permissions needed for starting, stopping, and binding to the service, as well as make specific service calls. After it’s been implemented, an Android service can be started using the Context.startService() method. If the service was already running when the startService() method was called, these subsequent calls don’t start further instances of the service.The service continues to run until either the Context.stopService() method is called, or the service completes its tasks and stops itself using the stopSelf() method. To connect to a service, interested applications use the Context.bindService() method to obtain a connection. If that service is not running, it is created at that time.After the connection is established, the interested applications can begin making requests of that service, if the applications have the appropriate permissions. For example, a Magic Eight Ball application might have an underlying service that can receive yes-or-no questions and provide Yoda-style answers.Any interested application could connect to the Magic Eight Ball service, ask a question (“Will my app flourish on the Android Market?”) and receive the result (“Signs point to Yes.”).The application can then disconnect from the service when finished using the Context.unbindService() method. Warning Like applications, services can be killed by the Android operating system under low-memory conditions. Also like applications, services have a main thread that can be blocked, causing the system to become unresponsive. Always offload intensive processing to worker threads, even when implementing a service.
Creating a Service
Creating an Android service involves extending the Service class and adding a service block to the AndroidManifest.xml permissions file.The GPXService class overrides the onCreate(), onStart(), onStartCommand(), and onDestroy() methods to begin with. Defining the service name enables other applications to start the service that runs in the Creating a Service 439 background and stop it. Both the onStart() and onStartCommand() methods are essentially the same, with the exception that onStart() is deprecated in API Levels 5 and above. (The default implementation of the onStartCommand() on API Level 5 or greater is to call onStart() and returns an appropriate value such that behavior will be compatible to previous versions.) In the following example, both methods are implemented. Tip Many of the code examples provided in this chapter are taken from the SimpleService and UseService applications. The source code for these applications is provided for download on the book website. For this example, we implement a simple service that listens for GPS changes, displays notifications at regular intervals, and then provides access to the most recent location data via a remote interface.The following code gives a simple definition to the Service class called GPXService: public class GPXService extends Service { public static final String GPX_SERVICE = “com.androidbook.GPXService.SERVICE”; private LocationManager location = null; private NotificationManager notifier = null; @Override public void onCreate() { super.onCreate(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } @Override public void onStartCommand(Intent intent, int flags, int startId) { super.onStart(intent, startId); } @Override public void onDestroy() { super.onDestroy(); } } You need to understand the lifecycle of a service because it’s different from that of an activity. If a service is started by the system with a call to the Context.StartService() method, the onCreate() method is called just before the onStart() or onStartCommand() methods. However, if the service is bound to with a call to the 440 Chapter 21 Working with Services Context.bindService() method, the onCreate() method is called just before the onBind() method.The onStart() or onStartCommand() methods are not called in this case.We talk more about binding to a service later in this chapter. Finally, when the service is finished—that is, it is stopped and no other process is bound to it—the onDestroy() method is called. Everything for the service must be cleaned up in this method.