Sunday, 19 July 2020

Looper, Handler and HandlerThread

Looper, Handler and HandlerThread

All of these are used to execute the tasks in Asynchronous programming.
The main thread in android is build with handler and Looper, so to create the unblocked responsive UI , we need to use these topics.

First let us understand the concepts before our hands get dirty with programming.
                 In Java we have threads, but main disadvantage of thread is it will die after it executes Run method.So, to use of more threads to execute our tasks will create a slowness of the application and it is a overhead to maintain the thread states.To overcome this we always use optimum of threads to execute our tasks.

MessageQueue: Which has tasks called messages which should be processed.
Handler enqueues tasks in the Messagequeue using Looper also executes them when tasks comes out of Messagequeue
Looper is a worker thread , that loops Messagequeue and send messages to corresponding Handler to process.
Finally Thread gets terminated when it is calling Looper's "quit" method.

Note: One thread can have one Looper method and its associate with multiple unique Handler methods.

Creating looper and messagequeue for a thread.

  1. A thread gets a looper and messagequeue by calling looper.prepare() method.
  2. Looper.prepare() method identifies thread and creates looper and messagequeue object and associates the thread with ThreadLocal storage class.
  3. Looper.loop must be called to start the associate looper.
  4. Similarly looper must be terminated when its called looper.quit() method.

class LooperThread extends Thread{
   public Handler mhandler;
   
  public void run(){
  Looper.prepare();
  mhandler= new Handler(){
  public void handlmessage(Message message){
  //Process incoming messages to execute 
  NonUI/Background tasks.  

}
};

}

}

Creating Handler for a thread:

A handler implicitly associates with a thread that instantiates with the thread's Looper,but we explicitly tie with a Thread by passing a thread Looper to its constructor of the Handler.

Sending messages to the Messagequeue via Handler can be done in two ways.

1.Message: It is a class that defines various methods to deal with message data,To send an object we set the obj variable.

Message  msg=new Message();
msg.obj="new message";
handler.sendmessage(msg);

2.Runnable: A runnable can also be posted in the messagequeue,Ex: Posting and running in the main thread.
new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { // this will run in the main thread
});


private class MyHandlerThread extends HandlerThread { Handler handler; public MyHandlerThread(String name) { super(name); } @Override protected void onLooperPrepared() { handler = new Handler(getLooper()) { @Override public void handleMessage(Message msg) { // process incoming messages here // this will run in non-ui/background thread } }; } 
}


1. Looper is only prepared when HandlerThread()'s start() method is called, i.e after thread Running.
2. Handler can be associates with HandlerThread only Looper is prepared.


Other way to create the HandlerThread:
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
Note: 
HandlerThread needs to call myHandlerThread.quit() to free the resources and stop the execution of the thread.






No comments:

Post a Comment