Background Processing in Android

Julián Falcionelli
6 min readJun 7, 2017

Those who have been developing Android for a while should know the variety of alternatives to do background tasks that are available.

Today in a summarized way I will try to explain the best-known alternatives with the problems of each one.

But before,

What is it?

Background processing in Android refers to the execution of tasks in different threads than the Main Thread, also known as UI Thread, where views are inflated and where the user interacts with our app.

Why background processing?

  • To avoid UI blockages by I/O events and prevent the famous “Application Not Responding” dialog. A freezing app means bad UX.
  • Some operations are not allowed to run in the Main Thread, such as HTTP calls.
  • To improve performance.

So, here are some of the best-known alternatives,

Thread & Handler

Create a Thread with a Runnable and do the heavy operation, when the heavy operation ends call the handler created earlier on the UI Thread.

By default the views have a handler, so you can do View.post(). The Handler is the means of communication between the heavy task running on the created thread and the UI Thread.

Activity.runOnUiThread() simply posts to a main thread Handler internally.

Other way,

Problems:

  • No support for configuration changes, in other words, if our application supports both orientations (landscape and portrait) we have to handle the states of the Threads and Handlers when the user rotates his device.
  • Boilerplate code and un-friendly read.
  • No error handler.

IntentService

Useful when it’s necessary to run tasks in the background that don’t affect the UI. They are completely decoupled from view, ie they are not affected by the life cycle of the Activity.

It must be declared in the AndroidManifest.xml just like any other Service. Then it can then be started by sending an Intent (that can include any parameters).

Problems:

  • Doesn’t have direct communication with the UI.

The way to send results to the view is through Broadcast Receivers or some event bus strategy.

AsyncTask

Run instructions in the background and synchronize again with the Main Thread. Useful for short background operations.

How does it work?

Problems:

  • No support for configuration changes.
  • No error handler, so we have to ask onPostExecute whether the result is an error or not.
  • Complex chain of asynchronous operations, so it is advisable that the operations performed in the background are all synchronized to avoid the famous Callback Hell.
  • Each AsyncTask instance can be executed only/just one time.

Loader & Cursor Loader

It allows you to load data asynchronously in an Activity or Fragment. They can monitor the source of the data and deliver new results when the content changes.

  • Loaders persist and cache results across configuration changes to prevent duplicate queries.
  • Loaders can implement an observer to monitor for changes in the underlying data source. For example, Android provides a default Loader implementation to handle SQlite database connections, the CursorLoader class, which automatically registers a ContentObserver to trigger a reload when data changes.

Problems:

  • This implementation takes time compared to other alternatives.
  • No error handler.

RxAndroid

Here's the last alternative that I will show.

This alternative is based on Reactive Programming, which in a nutshell is a paradigm oriented around data flows and the propagation of change, a mix of the Observer and Iterable Pattern.

In order to use this paradigm, we have the RxJava library which is an implementation of the Reactive extensions and the RxAndroid library which provides mechanisms to communicate with the main thread.

To setup RxAndroid to your project check this: https://github.com/ReactiveX/RxAndroid

To understand this a little more this alternative is important to know which are the main components of it.

Components:

  • Observables that would become our data sources
  • Observers are those who subscribe to observables to display data in the UI.
  • Operators that will allow us to easily process the data structures that produce observables. There are a lot!
  • Schedulers are the component in Rx that tells observable and observers on which thread they should run.

Before starting with this some examples it is very important to be familiar with lambda operations introduced in Java 8. This is mainly important because most of the documentation and examples are developed in this way.

So,

Lambda expressions

It serves to reduce the amount of code and make it more agile to read.

To support Lambda expressions check this: https://developer.android.com/guide/platform/j8-jack.html

For example, suppose we have a reduce operation that receives as a parameter an anonymous class. The usual form would be:

With the → Lambda Operator would be:

And if the called method has the same parameters as the override method we can use the :: Lambda Operator

Easy, right?

Let’s see this with Rx!

First, see Rx without lambda:

There we have an Observable that emits 5 items (1, 2, 3, 4 and 5), and the items a filtered by the Filter operator, which only leaves the odd ones.

Then we subscribe to that Observer by the subscribe operator. In the subscribe we need to overwrite all those methods.

If we use lambda it would be:

Let's see a real example!

Usually, we have to make calls to an API and update some element of our view, with Rx that would be:

How it works?

There we used the Single observable type, which, unlike the Observable type, only emits a value (which is the most common). So, the subscribe only have 2 methods to override, the onSuccess and the onError.

Then the first thing we do is create the observable and set the behavior of the same through the subscribe method of the SingleOnSubscribe instance, which receives as a parameter an emitter, which as its name says is responsible for issuing the values. This is where we have to perform all the operations that produce I/O blocks, such as: making a call to an API, reading a record of a database, accessing the SharedPreferences or whatever and finally returning the result of the blocking operation by calling the onSuccess method of the emitter. In case an Exception occurs the error will be dispatched to the onError method of the emitter.

The subscribeOn defines that the blocking operation must be done in the I /O thread, and observeOn defines that the result will be dispatched to the main thread. This is very important to set it since by default Rx is synchronous.

The operator doOnSubscribe will run every time someone subscribes, in this case we will show a progress bar or something to indicate to the user that an operation is being performed, and the doFinally will be executed when the operation ends, either successfully or not , So here we can hide the progress bar.

Finally, we subscribe to execute the desired operation and dispatch the result to the processResult method (which receives the result of the blocking operation as a parameter, in this case, a String) or to the ProcessError method (which receives a Throwable as a parameter).

There are a lot of Observables and Observers types and useful Operators so I recommend you take a look directly at the official documentation!

http://reactivex.io/

Conclusion

As you can see Rx is relatively easy to use, doesn’t generate much overhead in the code (no boilerplate code), has a lot of operations that will facilitate the handling of data structures, and prevent the famous Callback Hell and finally has an error handler. However, it doesn’t solve the problem of persistence to changes in configuration.

So what should I use? It depends on the situation, the size of the project, and other factors.

I’m not a fan of coupling base code to a third-party library, but I think Rx earned my respect.

Based on my experience, my recommendation is:

Definitely go for an MVP architecture instead of the default MVC.

I also like to use Repository pattern to abstract the views (Presenters in case of using MVP) the source of the data.

Rx would come to be in repositories/managers and if you choose to use MVP you must try to have all Rx related in the layer of the Presenters and not in the Activities/Fragments.

Then for certain operations in the view the handlers are very useful.

Then if we are going to have a database and a lot of information flow in our application CursorLoaders (Loaders + ContentProviders) is a very good option.

I hope you have understood everything, any questions/advice don't hesitate to write!

Next Read: Background Processing Part 2 by Ezequiel Excoffon. There you can learn about the latest available tools (JobSchedulers, Kotlin Coroutines, and more !) for running long operations in background.

--

--