How do you display a Toast from a background thread on Android?

AndroidMultithreadingAndroid Toast

Android Problem Overview


How can I display Toast messages from a thread?

Android Solutions


Solution 1 - Android

You can do it by calling an Activity's runOnUiThread method from your thread:

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
    }
});

Solution 2 - Android

I like to have a method in my activity called showToast which I can call from anywhere...

public void showToast(final String toast)
{
	runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show());
}

I then most frequently call it from within MyActivity on any thread like this...

showToast(getString(R.string.MyMessage));

Solution 3 - Android

This is similar to other answers, however updated for new available apis and much cleaner. Also, does not assume you're in an Activity Context.

public class MyService extends AnyContextSubclass {
    
    public void postToastMessage(final String message) {
        Handler handler = new Handler(Looper.getMainLooper());

        handler.post(new Runnable() {

            @Override
            public void run() {
                Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
            }
        });
    }
}

Solution 4 - Android

One approach that works from pretty much anywhere, including from places where you don't have an Activity or View, is to grab a Handler to the main thread and show the toast:

public void toast(final Context context, final String text) {
  Handler handler = new Handler(Looper.getMainLooper());
  handler.post(new Runnable() {
    public void run() {
      Toast.makeText(context, text, Toast.LENGTH_LONG).show();
    }
  });
}

The advantage of this approach is that it works with any Context, including Service and Application.

Solution 5 - Android

Like this or this, with a Runnable that shows the Toast. Namely,

Activity activity = // reference to an Activity
// or
View view = // reference to a View
        
activity.runOnUiThread(new Runnable() {
	@Override
	public void run() {
		showToast(activity);
	}
});
// or
view.post(new Runnable() {
	@Override
	public void run() {
		showToast(view.getContext());
	}
});

private void showToast(Context ctx) {
	Toast.makeText(ctx, "Hi!", Toast.LENGTH_SHORT).show();
}

Solution 6 - Android

Sometimes, you have to send message from another Thread to UI thread. This type of scenario occurs when you can't execute Network/IO operations on UI thread.

Below example handles that scenario.

  1. You have UI Thread
  2. You have to start IO operation and hence you can't run Runnable on UI thread. So post your Runnable to handler on HandlerThread
  3. Get the result from Runnable and send it back to UI thread and show a Toast message.

Solution:

  1. Create a HandlerThread and start it
  2. Create a Handler with Looper from HandlerThread:requestHandler
  3. Create a Handler with Looper from Main Thread: responseHandler and override handleMessage method
  4. post a Runnable task on requestHandler
  5. Inside Runnable task, call sendMessage on responseHandler
  6. This sendMessage result invocation of handleMessage in responseHandler.
  7. Get attributes from the Message and process it, update UI

Sample code:

    /* Handler thread */

    HandlerThread handlerThread = new HandlerThread("HandlerThread");
    handlerThread.start();
    Handler requestHandler = new Handler(handlerThread.getLooper());
    
    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();
        }
    };

    for ( int i=0; i<5; i++) {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {
              
                    /* Add your business logic here and construct the 
                       Messgae which should be handled in UI thread. For 
                       example sake, just sending a simple Text here*/

                    String text = "" + (++rId);
                    Message msg = new Message();

                    msg.obj = text.toString();
                    responseHandler.sendMessage(msg);
                    System.out.println(text.toString());

                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        };
        requestHandler.post(myRunnable);
    }


   

Useful articles:

handlerthreads-and-why-you-should-be-using-them-in-your-android-apps

android-looper-handler-handlerthread-i

Solution 7 - Android

  1. Get UI Thread Handler instance and use handler.sendMessage();
  2. Call post() method handler.post();
  3. runOnUiThread()
  4. view.post()

Solution 8 - Android

You can use Looper to send Toast message. Go through this link for more details.

public void showToastInThread(final Context context,final String str){
	Looper.prepare();
    MessageQueue queue = Looper.myQueue();
    queue.addIdleHandler(new IdleHandler() {
         int mReqCount = 0;

         @Override
         public boolean queueIdle() {
             if (++mReqCount == 2) {
                  Looper.myLooper().quit();
                  return false;
             } else
                  return true;
         }
    });
	Toast.makeText(context, str,Toast.LENGTH_LONG).show();		
	Looper.loop();
}

and it is called in your thread. Context may be Activity.getContext() getting from the Activity you have to show the toast.

Solution 9 - Android

I made this approach based on mjaggard answer:

public static void toastAnywhere(final String text) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        public void run() {
            Toast.makeText(SuperApplication.getInstance().getApplicationContext(), text, 
                    Toast.LENGTH_LONG).show();
        }
    });
}

Worked well for me.

Solution 10 - Android

Kotlin Code with runOnUiThread

runOnUiThread(
        object : Runnable {
            override fun run() {
                Toast.makeText(applicationContext, "Calling from runOnUiThread()", Toast.LENGTH_SHORT)  
            }
        }
)

Solution 11 - Android

I encountered the same problem:

E/AndroidRuntime: FATAL EXCEPTION: Thread-4
              Process: com.example.languoguang.welcomeapp, PID: 4724
              java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
                  at android.widget.Toast$TN.<init>(Toast.java:393)
                  at android.widget.Toast.<init>(Toast.java:117)
                  at android.widget.Toast.makeText(Toast.java:280)
                  at android.widget.Toast.makeText(Toast.java:270)
                  at com.example.languoguang.welcomeapp.MainActivity$1.run(MainActivity.java:51)
                  at java.lang.Thread.run(Thread.java:764)
I/Process: Sending signal. PID: 4724 SIG: 9
Application terminated.

Before: onCreate function

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});
thread.start();

After: onCreate function

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});

it worked.

Solution 12 - Android

java 11:

var handler = new Handler(Looper.getMainLooper);
handler.post(() -> Toast.makeText(your_context, "Hi!", Toast.LENGTH_SHORT).show());

Lambdas are available in java 8 though. var is introduced in java 11.

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
QuestionAruthaView Question on Stackoverflow
Solution 1 - AndroidLauri LehtinenView Answer on Stackoverflow
Solution 2 - AndroidmjaggardView Answer on Stackoverflow
Solution 3 - AndroidChrisCMView Answer on Stackoverflow
Solution 4 - AndroidMike LarenView Answer on Stackoverflow
Solution 5 - AndroidyanchenkoView Answer on Stackoverflow
Solution 6 - AndroidRavindra babuView Answer on Stackoverflow
Solution 7 - AndroidKerwin YouView Answer on Stackoverflow
Solution 8 - AndroidVinoj John HosanView Answer on Stackoverflow
Solution 9 - AndroidÂngelo PolottoView Answer on Stackoverflow
Solution 10 - AndroidPratik DodiyaView Answer on Stackoverflow
Solution 11 - AndroidLanguoguangView Answer on Stackoverflow
Solution 12 - AndroidRyanView Answer on Stackoverflow