Why to use Handlers while runOnUiThread does the same?

AndroidMultithreadingAndroid AsynctaskHandler

Android Problem Overview


I have come across both Handlers and runOnUiThread concepts. But to me it still seems to be a doubt as on which facts do they differ exactly.

They both are intended to do UI actions from a background thread. But what are the factors that are to be considered while we choose among the two methods.

For example consider a Runnable Thread which performs a web service in the background and now I want to update the UI.

What would be the best way to update my UI? Should I go for Handler or runOnUiThread?

I still know I could use a AsyncTask and make use of onPostExecute. But I just want to know the difference.

Android Solutions


Solution 1 - Android

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.

Solution 2 - Android

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.

Solution 3 - Android

Handler have many work like message passing and frequent UI update if you start A Thread for any running a task .A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue ,, which is very useful in many application like bluetooth chat ,, wifi chat ... and handler has as Method PostDelay and PostAtTime by which you can play around any view to animate and change visibility and so on

You must look in this

http://developer.android.com/guide/components/processes-and-threads.html

http://developer.android.com/tools/testing/activity_testing.html

Solution 4 - Android

Following HitOdessit's answer.

You can create a class like this.

public class Global{
    private static Handler mHandler = new Handler(Looper.getMainLooper());
    public static void runOnUiThread(Runnable action){
        mHandler.post(action);
    }
}

And then call it like this.

Global.runOnUiThread(new Runnable(){
    //Your code
});

And this can be run from anywhere (where you have access to your Global class).

Solution 5 - Android

>What would be the best way to update my UI? Should I go for Handler or runOnUiThread?

If your Runnable needs to update UI, post it on runOnUiThread.

But it's not always possible to post Runnable on UI Thread.

Think of scenario, where you want need to execute Network/IO operation Or invoke a web service. In this case, you can't post Runnable to UI Thread. It will throw android.os.NetworkOnMainThreadException

These type of Runnable should run on different thread like HandlerThread. After completing your operation, you can post result back to UI Thread by using Handler, which has been associated with UI Thread.

public void onClick(View view) {

    // onClick on some UI control, perform Network or IO operation

    /* Create HandlerThread to run Network or IO operations */
    HandlerThread handlerThread = new HandlerThread("NetworkOperation");
    handlerThread.start();

    /* Create a Handler for HandlerThread to post Runnable object */
    Handler requestHandler = new Handler(handlerThread.getLooper());

   /* Create one Handler on UI Thread to process message posted by different thread */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler);
    NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler);
    requestHandler.post(r1);
    requestHandler.post(r2);

}

class NetworkRunnable implements Runnable{
    String url;
    Handler uiHandler;

    public NetworkRunnable(String url,Handler uiHandler){
        this.url = url;
        this.uiHandler=uiHandler;
    }
    public void run(){
        try {
            Log.d("Runnable", "Before IO call");
            URL page = new URL(url);
            StringBuffer text = new StringBuffer();
            HttpURLConnection conn = (HttpURLConnection) page.openConnection();
            conn.connect();
            InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
            BufferedReader buff = new BufferedReader(in);
            String line;
            while ((line = buff.readLine()) != null) {
                text.append(line + "\n");
            }
            Log.d("Runnable", "After IO call:"+ text.toString());

            Message msg = new Message();

            msg.obj = text.toString();

            /* Send result back to UI Thread Handler */
            uiHandler.sendMessage(msg);
     

        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndro SelvaView Question on Stackoverflow
Solution 1 - AndroidHitOdessitView Answer on Stackoverflow
Solution 2 - AndroidAnimeshView Answer on Stackoverflow
Solution 3 - AndroidVipin SahuView Answer on Stackoverflow
Solution 4 - Androiduser7366285View Answer on Stackoverflow
Solution 5 - AndroidRavindra babuView Answer on Stackoverflow