In Android applications, like in all mobile applications, responsiveness is often the key to offer great user experience. It’s essential to avoid blocking user interface. In some cases, you will need to process long-running operations. To void affecting user interface’s responsiveness, you will need to use background service.

Deriving from IntentService class, a background service is a straightforward structure for running an application on a single background thread. Some readers could ask me, an what about AsyncTask ? IntentService has some advantages in front of AsyncTask. Indeed, it isn’t affected by most user interface lifecycle events. So, it continues to run in circumstances that would shut down an AsyncTask.

However, you must know that IntentService has some limitations :

  • An IntentService can’t interact directly with your user interface. To achieve that and put results in the UI, you have to send them to an Activity.
  • Work requests run sequentially which implies that if an operation is running in an IntentService and you send if another request, the request waits until the first operation is finished.
  • An operation running on an IntentService can’t be cancelled or interrupted.

Despite of these limitations, IntentService is often the best way to perform simple background operations.


1/ Create an IntentService

First, we need to create our IntentService implementation by defining a class that extends IntentService, and within it, define a method that overrides onHandleIntent() method like that :


public class MyService extends IntentService {
   @Override
   protected void onHandleIntent(Intent workIntent) {
      String inputData = workIntent.getDataString();
      ...
      // Process work by using input data
      ...
   }
}

 

2/ Define the IntentService in your Android Manifest

Each IntentService needs to be defined inside the Android Manifest of an application. To achieve that, you need to add a service entry inside application tag :


<application …>
   <service android:name=".MyService" />
 </application>

 

3/ Create and Start the IntentService

Now that IntentService is implemented and defined, we must create and start it inside a method like that :


Intent mServiceIntent = new Intent(getActivity(), MyService.class);
 // set work data to send to MyService for processing
 mServiceIntent.setData(Uri.parse(dataUrl));
 getActivity().startService(mServiceIntent);

Once startService method is called with the explicit intent for MyService, the onHandleIntent method of MyService is called by OS.

 

4/ Communicate work status from an IntentService

Once your long-running operations are ended, you could want to communicate that to an Activity for example. To send the status of a work request from an IntentService to other components, we need to use a Broadcast operation. But first, we’re going to send an Intent like that :


public final class Constants {
   public static final String BROADCAST_ACTION = "com.example.ssaurel.myservice.BROADCAST";
   public static final String EXTENDED_DATA_STATUS = "com.example.ssaurel.myservice.STATUS";
}

public class MyService extends IntentService {

   @Override
   protected void onHandleIntent(Intent workIntent) {
      // long-running work …

      Intent localIntent = new Intent(Constants.BROADCAST_ACTION)
      // add status into the Intent
         .putExtra(Constants.EXTENDED_DATA_STATUS, status);

      // Broadcasts the Intent to receivers in this app.
      LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
   }
}

 

5/ Receive status Broadcasts from an IntentService

Last step is to receive status Broadcasts from an IntentService. You need to create a BroadcastReceiver implementation :


private class ResponseReceiver extends BroadcastReceiver {

   public ResponseReceiver () {
   }

   // Called when the BroadcastReceiver gets an Intent it's registered to receive
   public void onReceive(Context context, Intent intent) {
      // handle intent and make some actions ...
   }
}

To be notified, we must register this broadcast receiver inside an Activity for example with following lines :


IntentFilter statusIntentFilter = new IntentFilter(Constants.BROADCAST_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(new ReponseReceiver(), statusIntentFilter);

That’s all ! However, you must note that sending an broadcast Intent doesn’t start or resume an Activty. Best practice to notify user about an event that happened in the background while your app is not visible is to use a Notification. You must never start an Activity to answer to an incoming broadcast Intent. Consider that as a golden rule !