Search code examples
androidandroid-handlerthread

Why would a background thread spawn its own Handler & Looper


Why would a background thread spawn its own Handler & Looper just to modify UI's component .I know that in simple terms:

  • Looper : Loop and execute tasks in a message queue

  • Handler : posting the tasks to the queue

Have a look at this snippet I took from article in internet

public class MyActivityV2 extends Activity {

   private Handler mUiHandler = new Handler();
   private MyWorkerThread mWorkerThread;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      mWorkerThread = new MyWorkerThread("myWorkerThread");
      Runnable task = new Runnable() {
         @Override
         public void run() {
            for (int i = 0; i < 4; i++) {
               try {
                  TimeUnit.SECONDS.sleep(2);
               } catch (InterruptedException e) {
                  e.printStackTrace();
               }
               if (i == 2) {
                  mUiHandler.post(new Runnable() {
                     @Override
                     public void run() {
                        Toast.makeText(MyActivityV2.this,
                            "I am at the middle of background task",
                            Toast.LENGTH_LONG)
                            .show();
                     }
                  });
               }
            }
            mUiHandler.post(new Runnable() {
               @Override
               public void run() {
                  Toast.makeText(MyActivityV2.this,
                      "Background task is completed",
                      Toast.LENGTH_LONG)
                      .show();
               }
            });
         }
      };

      // MyWorkerThread == HandlerThread
      mWorkerThread.start();
      mWorkerThread.prepareHandler();
      // 2 starting of thread
      mWorkerThread.postTask(task);
      mWorkerThread.postTask(task);
   }

   @Override
   protected void onDestroy() {
      mWorkerThread.quit();
      super.onDestroy();
   }
}

//MyWorkerThread.java
 class MyWorkerThread extends HandlerThread {

   private Handler mWorkerHandler;

   public MyWorkerThread(String name) {
      super(name);
   }

   public void postTask(Runnable task){
      mWorkerHandler.post(task);
   }

   public void prepareHandler(){
      mWorkerHandler = new Handler(getLooper());
   }
}

It's either I'm completely misunderstanding the code or lack of thread foundation in Android. So I'm sorry.

The background thread basically repeats itself (twice). The main idea is manipulation UI component through the background thread.

Have a look at this:

mWorkerHandler

Why would the background thread create its own handler, if its a matter of manipulation UI's component, why doesn't it just take a reference of UI thread handler and posting runnable through the handler.

and

 mWorkerHandler = new Handler(getLooper());

which is creating its own looper (background thread's looper), which indicates that the background thread creating its own Message Queue. Shouldn't it be supposed to just play around with the message queue of main thread and not background thread.

Thanks in advance.


Solution

  • I can't vouch for a random article on the Internet, but this code is using Handlers correctly.

    This line creates a handler that runs code on the UI thread:

    private Handler mUiHandler = new Handler();
    

    This method creates a handler that runs code in the background thread:

    public void prepareHandler(){
      mWorkerHandler = new Handler(getLooper());
    }
    

    These lines post the Runnable to the background thread:

    mWorkerThread.postTask(task);
    mWorkerThread.postTask(task);
    

    So in a nutshell, a background thread would use a looper and handler for the same reason the UI thread uses them: so code on other threads can post messages and runnables to it.