Search code examples
androidandroid-handlerandroid-looperandroid-threadandroid-threading

What is the difference between these methods for running code on UI Thread?


There are different methods posted on the web on how to run code on the UI thread. They all accomplish the same task, however, I really want to know the difference between these methods.

Method 1:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

Method 2:

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

Method 3:

 runOnUiThread(new Runnable() {
     @Override
     public void run() {
     // Code here will run in UI thread
     }
 });

Solution

  • In Android, a Thread might have one Looper or MessageQueue. Handler is used to send Message or post Runnable to MessageQueue of a Thread, and it must always be associated with a Looper or a MessageQueue of a Thread.

    Method 1

    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            // Code here will run in UI thread
        }
    });
    

    When open an app, Android create a new thread (called main thread or UI thread) with a Looper and MessageQueue, this thread is used to render UI and process input events from users.

    The above code is create a Handler and associated with Looper of UI thread, so the runnable will be queued to MessageQueue of UI thread, and will be executed later.

    Method 2

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            // Code here will run in UI thread
        }
    });
    

    Creating a Handler and associated with Looper of current thread, there are 3 cases:

    • If this code is executed on UI thread, then the runnable will be queued to MessageQueue of UI thread and will be executed later.
    • If this code is executed on a background thread, if this thread has a Looper, then the runnable will be queued to MessageQueue of background thread and will be executed later.
    • If this code is executed on a background thread and this thread has no Looper, then an exception will be thrown.

    Method 3

    runOnUiThread(new Runnable() {
         @Override
         public void run() {
         // Code here will run in UI thread
         }
    });
    

    runOnUiThread is just a utility method of Activity, it used when you want to execute some code on UI thread. The logic behind this method is if current thread is UI thread, then execute it immediately, otherwise used Handler to post a message to MessageQueue of UI thread (like method 1).