In our
previous tutorial about IntentService we saw that a BroadcastReceiver
can be used as a means of communication between the Service and the
calling client. Hower this method cannot be used for frequent
and fast calls, such as for progress
updates. For this purpose we have to use a different approach...
For more
information about binding Services and the way they are connected to
a calling Activity, please refer to my previous tutorials.
SERVICE
First
of all we have to define a public
interface inside our Service as a means
of communication between the Service and the calling Activity:
public
interface InterfaceCallback {
void
onProgressUpdate(int progress);
void
onTaskCompleted(MyResult myResult);
}
where
MyResult
is a user defined class
carrying the results of the operation performed by the Service in the
background.
The
next step is to connect our Service to the calling Activity. To do
this, we define an instance variable
of the type InterfaceCallback
and create a public method
that will be called by the calling Activity to connect itself to the
Service (the following code goes inside the Service class):
private
InterfaceCallback interfaceCallback;
...
public
void setInterfaceCallback(InterfaceCallback interfaceCallback) {
this.interfaceCallback
= interfaceCallback;
}
Now
our Service is ready to communicate with the calling Activity using
the interfaceCallback
reference.
For example, if we want to
notify the updates
of a background task (from the onProgressUpdate
method of an AsyncTask, for instance) we can call:
interfaceCallback.onProgressUpdate(progress);
In the
same way, if we need to communicate that the background operation has
been completed and send and object
containing the results, we can simply call:
interfaceCallback.onTaskCompleted(myResult);
CALLING ACTIVITY
To
make sure that our Activity can receive updates from the Service we
have to implement the previously
defined interface:
public
class CallingActivity extends Activity implements ServiceConnection,
MyService.InterfaceCallback {
//see
previous tutorial
}
Once
we have established a valid connection with the Service, we can
register our Activity
as a callback (our Activity overrides the InterfaceCallback methods
that are triggered by the Service):
@Override
public
void onServiceConnected(ComponentName componentName, IBinder iBinder)
{
MyService
myService = ((MyService.MyBinder) iBinder).getReference();
myService.setInterfaceCallback(this);
myService.startBackgroundTask();
}
@Override
protected
void onPause() {
super.onPause();
...
if(myService
!= null) {
myService.setInterfaceCallback(null);
unbindService(this);
}
}
Finally
we have to override the methods
onProgressUpdate
and onTaskCompleted
of the implemented InterfaceCallback
interface.
These methods, as we already
saw, are called from the Service to notify the connected Activity about the
progress updates and the completion of the background task:
@Override
public
void onProgressUpdate(int progress) {
//code
left out for brevity
}
@Override
public
void onTaskCompleted(MyResult myResult) {
//code
left out for brevity
}
to be continued...