Things to consider before running background tasks

Umesh Basnet
YoungInnovations' Blog
5 min readDec 30, 2016

--

You’ve started developing android app not so long ago and want to interact with the server to fetch data through API and save some data in local database. As soon as you run the app and perform task, you get a NetworkOnMainThreadException. Or, you are doing some heavy computation like finding Lucy’s mother’s third cousin’s husband’s elder sister’s sister-in-law’s father’s grand daughter (not an idle scenario but hope you get a gist), and suddenly you get the annoying App Not Responding (ANR) dialog and your app crashes. The worst nightmare for any developer! A simple solution for these issues - worker threads.

Everything that is visible to user in screen, happens in the main thread or UI thread. Every other thing that is not directly affecting the UI should be done in the worker thread. Android has provided lots of API to achieve this and some third party libraries are also available to simplify the job.

This article is not a tutorial on how to implement thread, tons of tutorial are already available all over the internet. This article focuses on the advantages and disadvantages of various threading mechanism in a hope to help you choose which way to go.

Thread:

Thread is the most direct and ultimate approach. Other ways provides a wrapper around thread. JVM allows different thread to run concurrently, so we can create our own worker thread and perform task in it without blocking the main thread.

Advantages:

  • It is simple to implement and easier to start.
  • Threadpool and executor can be used easily to prioritize and queue the task.
  • Handler and looper can be used to communicate between thread and activity
  • All other third party libraries or helper classes have thread in its core.

Disadvantages:

  • it is very basic and may not be favorable for complex task.
  • Lots of things to consider like activity life cycle.
  • If used directly as anonymous class in activity, it has hard reference of activity and hence memory leak.
  • UI interaction from thread is not possible, you will need handler for the communication.

AsyncTask:

AsyncTask is an android class that has a worker thread implementation inside it. So, we can use it directly without all the hassle of creating worker thread on our own.

Advantages:

  • Simple and straight forward to use, need just one method to override.
  • Static method AsyncTask.execute() can be used to for more easier approach.
  • Unlike Threads, AsyncTask provides callbacks in form ofonPreExecute(), onProgressUpdate(), onPostExecute() to notify task start, update and finish respectively which runs on main thread.

Disadvantages:

  • Can generate callback hell when executing inter related tasks.
  • By default runs task in serial. If parallel execution is required then you must call executeOnExecutor().
  • It does not survive configuration changes on their own.
  • One instance of Asynctask can perform the task only once. if you want to perform task again then you have to create new instance.

Service:

Service are used to perform long running task. They are accessible from all over the app and can be used for Inter Process Communication(IPC). Service does not perform task in a worker thread by itself. If required you need to create your own worker thread inside the Service.

IntentService:

IntentService is a service that has worker thread inside it. It can be used to perform same task on different set of data. If you need to play music or download data then Intent service is a good choice as they can be started as STICKY and terminates only after the task is completed, not when activity is destroyed.

Advantages:

  • Straight forward implementation, simple.
  • Handler or LocalBroadcastManager can be used for intercommunication between threads (UI and worker threads)
  • Available from all over the app and also capable of running in different process.
  • Can perform task even when app is closed with help of foreground service.
  • Has higher priority than activities so chances of termination from the platform is low.

Disadvantages:

  • Does not survive orientation change or configuration change.
  • Tasks are queued and performed serially.
  • Cannot interact with the main thread by default.

Loader:

Loader is the better implementation of thread with help to manage the thread against the lifecycle events of activities and fragments.

Advantages:

  • Simplification of thread management via callbacks like onCreateLoader(), onLoadFinished(), onLoadReset().
  • Can survive orientation change or configuration change by caching data and hence continuation of task is achieved.
  • Observable data fields can be implemented to actively listen for changes.
  • Android provides different loader subclasses like CursorLoader, AsyncTaskLoader for easier usage.

Disadvantages:

  • Depends on Activity or Fragment lifecycle, so they are destroyed with the activity or fragment
  • No guarantee that the task is completed.
  • Needs to be implemented in Activity/Fragment specifying the data type the loader is to deal with. Might lead to unwanted abstraction.

JobService and JobScheduler

JobService and JobScheduler was introduced in API 21 (Lollipop) to provide better control over the execution of the background task. Suppose you have lots of task like synchronization of data with the server which might consume lot of battery power or data. You want to perform such long extensive task when the device is charging and/or connected to wifi. That’s totally possible with the help of this API.

Advantages:

  • Can batch tasks together for better performance.
  • As mentioned earlier, you can define the favorable device status to run the task.
  • Survives device restart.

Disadvantages:

  • Not favorable if the task is time sensitive as the exact condition may not met
  • Relatively new API only supported from Lollipop.

Note: GCM Network Manager can be used instead which is backport and similar to JobScheduler.

RxJava

If you are familiar with functional programming then you might have heard of RxJava. It is the JVM implementation of the reactive approach. Along with RxAndroid, it provides the easiest API (in some ways) for the background processes and communication with main thread.It also makes code verbose and let’s you code in a flow.

Advantages:

  • Very easy to define in which thread you want to perform task and in which thread you want to handle result. Simply define subscribeOn() and observeOn() respectively.
  • Provides helper thread for background thread like Scheduler.io(), Schedulers.newThread() and Schedulers.computation();
  • Has a direct way to access main thread, just use AndroidSchedulers.mainThread().
  • Can perform tasks serially, parallely, concat result and so much more (read documentation to see the power of RxJava).
  • Easier to handle the exceptions.
  • No callback hell :)

Disadvantages:

  • Steep learning curve.
  • Debugging can be a tad harder.

These are the few things I learned this year. This may not be much and I may have left out things. Share your ideas, thought and other insights.

--

--