Services can be used by any application component that “hangs around” for a reasonable period of time. This includes activities, content providers, and other services. Notably, it does not include pure intent receivers (i.e., intent receivers that are not part of an activity), since those will get garbage collected immediately after each instance processes one incoming Intent
.
To use a service, you need to get an instance of the AIDL interface for the service, then call methods on that interface as if it were a local object. When done, you can release the interface, indicating you no longer need the service.
In this chapter, we will look at the client side of the Service/WeatherPlus
sample application. The WeatherPlus
activity looks an awful lot like the original Weather application — just a Web page showing a weather forecast as you can see in Figure 31-1.

Figure 31-1.
The difference is that, as the emulator “moves”, the weather forecast changes, based on updates provided by the service.
Bound for Success
To use a service, you first need to create an instance of your own ServiceConnection
class. ServiceConnection
, as the name suggests, represents your connection to the service for the purposes of making IPC calls. For example, here is the ServiceConnection
from the WeatherPlus
class in the WeatherPlus
project:
private ServiceConnection svcConn = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder binder) {
service = IWeather.Stub.asInterface(binder);
browser.postDelayed(new Runnable() {
public void run() {
updateForecast();
}
}, 1000);
}
public void onServiceDisconnected(ComponentName className) {
service = null;
}
};
Your ServiceConnection
subclass needs to implement two methods:
1. onServiceConnected()
, which is called once your activity is bound to the service
2. onServiceDisconnected()
, which is called if your connection ends normally, such as you unbinding your activity from the service
Each of those methods receives a ComponentName
, which simply identifies the service you connected to. More importantly, onServiceConnected()
receives an IBinder
instance, which is your gateway to the IPC interface. You will want to convert the IBinder
into an instance of your AIDL interface class, so you can use IPC as if you were calling regular methods on a regular Java class (IWeather.Stub.asInterface(binder)
).
To actually hook your activity to the service, call bindService()
on the activity:
bindService(serviceIntent, svcConn, BIND_AUTO_CREATE);
The bindService()
method takes three parameters:
1. An Intent
representing the service you wish to invoke — for your own service, it’s easiest to use an intent referencing the service class directly (new Intent(this, WeatherPlusService.class)
)
2. Your ServiceConnection
instance
3. A set of flags — most times, you will want to pass in BIND_AUTO_CREATE
, which will start up the service if it is not already running
After your bindService()
call, your onServiceConnected()
callback in the ServiceConnection
will eventually be invoked, at which time your connection is ready for use.
Request for Service
Once your service interface object is ready (IWeather.Stub.asInterface(binder)
), you can start calling methods on it as you need to. In fact, if you disabled some widgets awaiting the connection, now is a fine time to re-enable them.
However, you will want to trap two exceptions. One is DeadObjectException
— if this is raised, your service connection terminated unexpectedly. In this case, you should unwind your use of the service, perhaps by calling onServiceDisconnected()
manually, as shown previously. The other is RemoteException
, which is a more general-purpose exception indicating a cross-process communications problem. Again, you should probably cease your use of the service.
Prometheus Unbound
When you are done with the IPC interface, call unbindService()
, passing in the ServiceConnection
. Eventually, your connection’s onServiceDisconnected()
callback will be invoked, at which point you should null out your interface object, disable relevant widgets, or otherwise flag yourself as no longer being able to use the service.
For example, in the WeatherPlus implementation of onServiceDisconnected()
shown previously, we null out the IWeather
service object.
You can always reconnect to the service, via bindService()
, if you need to use it again.
Manual Transmission
In addition to binding to the service for the purposes of IPC, you can manually start and stop the service. This is particularly useful in cases where you want the service to keep running independently of your activities — otherwise, once you unbind the service, your service could well be closed down.
To start a service, simply call startService()
, providing two parameters: