How can I display Toast messages from a thread?
-
[This](http://stackoverflow.com/a/16886486/1919641) answer the question in detail. – mihirjoshi Jun 03 '13 at 03:16
-
this answer provide the shortest solution: http://stackoverflow.com/a/18280318/1891118 – Oleksii K. Jul 17 '14 at 10:29
14 Answers
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();
}
});

- 10,647
- 2
- 31
- 29
-
1I'm not sure I understand how to do this. I have my existing public void run(). I tried putting this code there. I know that's not right because it didn't work, but I am really stuck. – SwimBikeRun Mar 04 '12 at 06:04
-
14Is "activity" passed to the non-ui-thread in its constructor? What is the right way to get the activity object that you are using from within the separate thread? – snapfractalpop Mar 15 '12 at 17:26
-
Set the `Thread` object's reference to the `Activity` in the `Activity`'s `onResume`. Unset it in the `Activity`'s `onPause`. Do both under a `synchronized` lock that both the `Activity` and `Thread` respect. – JohnnyLambada Apr 24 '12 at 05:55
-
5sometimes there is no access to ```Activity``` instance, you can use simple helper-class instead, see here: http://stackoverflow.com/a/18280318/1891118 – Oleksii K. Aug 28 '13 at 09:27
-
6I've usually found that `MyActivity.this.runOnUiThread()` works just fine from within an inner `Thread`/`AsyncTask`. – Anthony Atkinson Apr 30 '14 at 17:39
-
-
`runOnUiThread` does not seem to be available in the newer version of android api. – Ryan Oct 19 '21 at 00:36
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));

- 2,389
- 1
- 23
- 45
-
3
-
1For TOAST, always use Application Context, not Activity Context! – Yousha Aleayoub Sep 21 '15 at 08:35
-
1
-
1@OneWorld, proofs: 1- For a toast message, the Google Dev Guide uses the application context and explicitly say's to use it. 2- http://stackoverflow.com/a/4128799/1429432 3- http://stackoverflow.com/a/10347346/1429432 4- https://groups.google.com/d/msg/android-developers/3i8M6-wAIwM/EQOdAZKxsQYJ – Yousha Aleayoub Feb 16 '16 at 17:30
-
@YoushaAleayoub There is a lot of discussion and guessing in the links you provided. E.g. RomainGuy says there is no memory leak in your proof no. 4. Some of the links are from the early days of Android in 2009. Also people say in the other links that you can use both contexts. Activity and application. Maybe you have a more up to date real evidence based proof? Do you have a link for 1? – OneWorld Feb 22 '16 at 10:36
-
1- outdated? lol dude they wont be updated, and you CANT find any updated article in this case. So follow the old(?) rules if you dont have any idea or cant prove it. – Yousha Aleayoub Feb 22 '16 at 15:42
-
If Google suggested us to use ApplicationContext, then they should make it easier to access it, and stop returning null in any case. e.g. fragment.getApplicationContext(). – Kimi Chiu Nov 02 '16 at 04:12
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();
}
});
}
}

- 18,425
- 3
- 49
- 76
-
When the context you have is not an activity that is the perfect answer. Thanks a lot! – francas Apr 03 '20 at 18:43
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
.

- 1,188
- 12
- 35

- 8,028
- 17
- 51
- 70
-
What if your app is backgrounded, and a service thread calls this code, will the toast display when the app is foregrounded? I'm curios what happens to the main application thread when the app backgrounded. Does it pause, and not execute tasks in the event loop? And then resume? – the_prole Oct 01 '21 at 15:24
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();
}

- 56,576
- 33
- 147
- 165
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.
- You have UI Thread
- You have to start IO operation and hence you can't run
Runnable
on UI thread. So post yourRunnable
to handler onHandlerThread
- Get the result from
Runnable
and send it back to UI thread and show aToast
message.
Solution:
- Create a HandlerThread and start it
- Create a Handler with Looper from
HandlerThread
:requestHandler
- Create a Handler with Looper from Main Thread:
responseHandler
and overridehandleMessage
method post
aRunnable
task onrequestHandler
- Inside
Runnable
task, callsendMessage
onresponseHandler
- This
sendMessage
result invocation ofhandleMessage
inresponseHandler
. - 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

- 37,698
- 11
- 250
- 211
- Get UI Thread Handler instance and use
handler.sendMessage();
- Call
post()
methodhandler.post();
runOnUiThread()
view.post()

- 37,698
- 11
- 250
- 211

- 51
- 1
- 3
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.

- 37,698
- 11
- 250
- 211

- 6,448
- 2
- 41
- 37
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.

- 8,463
- 2
- 36
- 37
Kotlin Code with runOnUiThread
runOnUiThread(
object : Runnable {
override fun run() {
Toast.makeText(applicationContext, "Calling from runOnUiThread()", Toast.LENGTH_SHORT)
}
}
)

- 2,337
- 1
- 19
- 12
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.

- 1,249
- 3
- 19
- 27

- 2,166
- 2
- 10
- 15
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.

- 356
- 1
- 6
- 26
Contrary to almost every answer here, Toast#makeText
and Toast#show
do NOT have to run on the UI thread. The only requirement is that it runs on a thread that has called Looper#prepare
.
The reasons for this is because toasts are handled and rendered by the OS, not the application. Internally, Toast#show
makes a call to a system service to enqueue the toast.
This means the following code is valid
private static class MyThread extends Thread {
public Handler handler;
@Override
public void run() {
Looper.prepare();
handler = new Handler(Looper.myLooper()) {
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
Looper.loop()
}
}
final private MyThread t = new MyThread();
// start and wait for t to start looping
private void onClick() {
t.handler.post(() -> Toast.makeText(this, "this works", Toast.LENGTH_SHORT).show());
}

- 11
- 2
Method in onCreate :
private void toastPublic(final String message){
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(getBaseContext(),""+message,
4 /*Toast.LENGTH_SHORT*/).show();
}});
}
Next : use in inside Thread

- 1
- 2