Understanding Loopers in Android

When it comes to android applications, we always wish that users find our application ui interactions smooth and swift. What about having a lot of complex task to be executed in the application? Will we have these complex tasks executed on the main thread or delegate these complex tasks to a helper or a different thread to do these?
These are importance scenarios we need to really give a thought about as an android developer. When the application is started, a thread by default is created which is bound to the process and this thread is the main thread or the UI thread. We cannot or dare not disturb this thread as it is focused on handling the drawing of views and its interactions.

Having a complex tasks to do means having these tasks delegated to a second thread or worker thread to have a smooth application without encountering this common ANR (Application Not Responding) as this tends to scare the users😂.

WHY LOOPERS IN THIS DISCUSSION

First of all, we cannot talk of a looper without mentioning Handlers and MessageQueue and Thread. When we have a lot of jobs to be executed, in fact a heavy one, first of all, we can use a thread with a handler; a thread should be created and it does not come with a looper by default. You could check this by running Looper.myLooper() and it will return null object.

So we need to prepare the looper in the thread first, in other words, initialise the looper. But the thread can do a work in the background without any looper halabaloo, so why a looper? It happens that when you have a lot of jobs to be done, the jobs needs to be placed in a message queue and this is done by a handler.
The handler gets the work to be processed from the user to the message queue through the sendMessage(), post(Runnable r), postDelayed(Runnable r, long delayMillis) etc of the handler object. The looper will take these tasks or jobs which is in the form of Runnables or Messages to be executed by calling Looper.loop().
So in other words, the loopers takes charge of how jobs in the message queue are executed. When the tasks in the message queue is done or idle, then the looper can stop by calling looper.quit() and this is handled by the system so you don’t need to worry about that.

this looper illustrator is from https://i.stack.imgur.com/UHY9C.png

IMPORTANCE OF LOOPERS

We could use thread to execute tasks in the background but one thing is when the tasks are completely executed, the thread dies and you would need to create another thread again and again if you want to execute another task in the background. This is not efficient and a lot of threads will be kept in memory and might even cause outOfMemory exception depending on the platform.

NB: Loopers keep thread alive

So in order to use thread and avoid this outOfMemory exception, we could create one thread and initialize the looper in the thread and also create a handler and use the handler to execute the tasks to be done in the background without inundating the memory with a lot of dead threads. Check the example below for your reference on how Loopers, Handlers and Threads are created together.

class LooperThread extends Thread {
public Handler mHandler;

public void run() {
Looper.prepare();

mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};

Looper.loop();
}
}

Without going through this, we could harness the use of HandlerThread too. This is already created by android and made ready to use. This handlerThread makes use of the Looper concept, so you could take and use. You just need to create the HandlerThread and start it as you would for a normal thread. Then you create a handler and pass the handler thread object’s looper to the Hander constructor and you are good to go. Now you can use the handler to execute all tasks in the background.

NB: when you are creating a HandlerThread, don’t forget to close the thread through its quit method as it stops the looper.

//create the HandlerThread
HandlerThread handlerThread = new HandlerThread("my Handler Thread");
handlerThread.start();

//create the Handler
Handler handler = new Handler(handlerThread.getLooper());

//Use the Handler to send message or post runnables as you deem fit and
//all these works will be done in the background.

//close the handler thread when done.
//I mostly close it in the onDestroy method in activity or fragment
handlerThread.quit();

Thanks for reading. To help others please click ❤ to recommend this article if you found it helpful.😍