Why to use Handlers while runOnUiThread does the same?

Handlers were the old way (API Level 1) of doing stuff, and then AsycTask (API Level 3) were introduced, along with a stronger focus on using runOnUIThread (API Level 1). You should avoid using handlers as much as possible, and prefer the other two depending on your need.


Activity.runOnUiThread() is a special case of more generic Handlers. With Handler you can create your own event query within your own thread. Using Handlers instantiated with the default constructor doesn't mean "code will run on UI thread" in general. By default, handlers are bound to the Thread from which they were instantiated from.

To create a Handler that is guaranteed to bind to the UI (main) thread, you should create a Handler object bound to Main Looper like this:

Handler mHandler = new Handler(Looper.getMainLooper());

Moreover, if you check the implementation of the runOnUiThread() method, it is using Handler to do the things:

  public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

As you can see from code snippet above, Runnable action will be executed immediately if runOnUiThread() is called from the UI thread. Otherwise, it will post it to the Handler, which will be executed at some point later.