Android Bound Services
Creating a Bound Service
When creating a service that provides binding, you must provide an IBinder
that provides the programming interface that clients can use to interact with the service. There are three ways you can define the interface:
- Extending the Binder class (service is private and runs in the same process as the client)
- Using a Messenger (service works across different processes)
- Using AIDL (more low-level)
Commonly we use the way of extending the binder class.
Extending the Binder Class
#1. Right click in your application package to new a Service, and name it whatever you like.
Let’s say we will have a MagellanService
.
#2. Create an inner class which extends Binder
, and make a method getService()
to return the instance of MagellanService
so clients can call public methods.
public class MagellanBinder extends Binder {
MagellanService getService() {
return MagellanService.this;
}
}
You’ll have it like:
#3. Finish the defualt existed onBind()
method, which returns the instance of Binder.
public class MagellanService extends Service {
private final IBinder mBinder = new MagellanBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
#4. Create some public methods so that clients can call them.
/** method for clients */
public String getHiFromService() {
return "Hi";
}
There you go! You will be having this like:
Create your Client
An example of an activity that binds to MagellanService and calls getHiFromService()
when a button is clicked:
#1. Defines callbacks for service binding, passed to bindService()
public class BindingActivity extends Activity {
MagellanService mService;
boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to MagellanService, cast the IBinder and get MagellanService instance
MagellanBinder binder = (MagellanBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
#2. Bind to your Service
@Override
protected void onStart() {
super.onStart();
// Bind to your service
Intent intent = new Intent(this, MagellanService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
- The first parameter of
bindService()
is anIntent
that explicitly names the service to bind (thought the intent could be implicit). - The second parameter is the
ServiceConnection
object. - The third parameter is a flag indicating options for the binding. It should usually be
BIND_AUTO_CREATE
in order to create the service if its not already alive. Other possible values areBIND_DEBUG_UNBIND
andBIND_NOT_FOREGROUND
, or0
for none.
#3. Unbind from the Service
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
#4. Attach the button in the layout file to this onButtonClick()
method with the android:onClick attribute
public void onButtonClick(View v) {
if (mBound) {
// Call a method from the MagellanService.
// 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.
String msg = mService.getHiFromService();
Toast.makeText(this, "Hi from Service: " + msg, Toast.LENGTH_SHORT).show();
}
}
For more sample code, see the LocalService.java class and the LocalServiceActivities.java class in ApiDemos.
Important Notes about Binding to a Service
- Always trap DeadObjectException exceptions, which are thrown when the connection has broken. This is the only exception thrown by remote methods.
- Objects are reference counted across processes.
- Usually pair the
binding
andunbinding
for handling the client’s lifecycle.- for
onStart()
+onStop()
- for
onCreate()
+onDestroy()
(heavy weight of the process, system more likely kill it) - *NOT* for
onResume()
+onPause()
- for
For more sample code, showing how to bind to a service, see the RemoteService.java class in ApiDemos.
Lifecycle of a Bound Service
Dish of the day
#肉屋うたがわ #fukuoka