Android Background Services with IntentService

We’ve discussed Services before that run on the application’s UI (main thread). Android provides us with IntentService (extends the Service class) that has all the properties of a Service’s lifecycle with increased process rank and at the same time allows processing tasks on a background (worker) thread. So using an IntentService you can run long-running operations in the background without affecting the app’s responsiveness and at the same time one of the biggest advantage of it is that, it isn’t affected by most of the user interface (Activity/Fragment) lifecycle events, hence continues to run even when the Activity is destroyed for instance.

Implementation

Let’s first quickly see how to implement and use an IntentService and later we’ll delve into it’s inner workings, features, etc. So just as you would do with any other Service, first you make an entry into the manifest file:

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

<service
    android:name="com.example.app.MyIntentService">
</service>

Now to the real part, implementing the IntentService:

public class MyIntentService extends IntentService {

    public MyIntentService(String name) {
        // Used to name the worker thread
        // Important only for debugging
        super(MyIntentService.class.getName());
        setIntentRedelivert(true);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // Invoked on the worker thread
        // Do some work in background without affecting the UI thread
    }
}

As you can see, we only overrode onHandleIntent() which is called on the background thread and this is where all your long running operations have to be executed. Other callbacks of a regular Service component like onStartCommand() are automatically invoked internally by IntentService so you should avoid overriding them.

Note the setIntentRedelivery(true) call in the constructor. This means if the process is killed before onHandleIntent() returns, it’ll be restarted and the last delivered intent will be redelivered.

As we’re done with the creation and implementation part, now we’ll see how to actually send work requests to it. Client components (Activity, Fragment, BroadcastReceiver, etc.) that wish to send a start request to the IntentService will have to create an Intent and pass it to Context.startService().

Intent intent = new Intent(this, MyIntentService.class);
// Put some data for use by the IntentService
intent.putExtra("foo", "bar");
startService(intent);

You won’t have to stop the IntentService as it calls stopSelf() internally.

Under the hood, an IntentService makes use of a HandlerThread to execute tasks in background and not an AsyncTask if that’s what you were wondering.

Sequential Task Execution

All the tasks submitted to an IntentService, independant of their originating component, will be queued up and executed sequentially. So if a particular task takes a long time to execute, it’ll hold up all the other subsequent requests that were submitted, until its done. Once all the task requests have been handled, the IntentService will stop itself, so you shouldn’t call stopSelf() yourself.

It is very important to remember that IntentService executor is per instance and not per application like AsyncTask. This means if there are multiple IntentService instances, every instance will have a background thread of its own to execute tasks sequentially independent of other IntentService instances. Basically every IntentService object creates a new HandlerThread for itself.

Updating Activity from IntentService

There’ll be times when you’d do some sort of operation from an IntentService and update and Activity’s user interface. In order to do this, the IntentService can send notifications/data to a LocalBroadcastManager in the Activity that can update the Activity. More on this topic in this excellent training material.

Another way to do something similar is to post a Runnable to the main thread Handler.

Asynchronous Execution in BroadcastReceiver

A BroadcastReceiver can be the entry point for an application if triggered by system services or another application. It runs on the UI thread when invoked, so any long running operations, as you know, should be executed asynchronously on a different thread.

Now you could spawn a new thread using the Thread class or let’s say AsyncTask which’ll continue to run even after the BroadcastReceiver is destroyed. A BroadcastReceiver component is only active during the execution of onReceive, then it’s destroyed. So if it is the entry point and is destroyed after onReceive is executed, this’ll make the current app process an empty process. An empty process is one that doesn’t have any app component (with a lifecycle) running.

This increases the chances of this process being killed which could happen anytime, even instantly. It could happen before the background task is finished.

An IntentService can be used to avoid this problem. Although as of API 11, extending the lifetime of a BroadcastReceiver is possible with BroadcastReceiver.goAsync(). I’ve discussed goAsync before in my article on broadcast receivers.

Conclusion

We went through how to implement an IntentService which is super simple to use for offloading tasks in the background. Best part about it is, sequential task processing, hence thread-safe. In terms of sequential task processing, HandlerThread and AsyncTask can be compared to it but then IntentService also has to advantage of running as an independant component which others don’t. That means if client component is an Activity which is destroyed at some point of time when the IntentService is doing its long running operation, it’ll continue to run.

You should definitely go through the source code of IntentService to learn a lot more about Android programming and concepts in general.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

One thought on “Android Background Services with IntentService”

  1. Greetings to all!

    Just sorry for this message, I hope You will believe me, because I do not lie and do not earn this, I really need help.

    It so happened that I was in strong credits, I’m from Russia, in June examination of the daughter, and I have no money at all, I’m working, but all the money spent on loans.

    Remains at all much. Please help who than can, I really are in a very difficult situation.

    WebMoney: Z260768518606

    Admin sorry if I violate the rules of the site.

    Many thanks to all.

Leave a Reply

Your email address will not be published. Required fields are marked *