I have a legacy IntentService
that attempts to use Toast messages to display error messages.1 I'd like the messages to be displayed, and have added code to get them on the correct thread. The simplest change would be to pass in the constructed Toast
object and then display it on the UI thread. However, the Toast only displays if I make it in the posted runnable, not if I pass in a pre-made Toast
.
This works:
@Override
protected void onHandleIntent(Intent intent) {
showToast("Error", Toast.LENGTH_LONG);
}
private void showToast(final String msg, final int duration) {
new Handler(getMainLooper()).post(new Runnable() {
@Override
public void run() {
// Make and show the toast in the posted runnable
Toast.makeText(getApplicationContext(), msg, duration).show();
}
});
}
This doesn't work:
@Override
protected void onHandleIntent(Intent intent) {
// Make the toast here
Toast myToast = Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_LONG);
showToast(myToast);
}
private void showToast(final Toast toast) {
new Handler(getMainLooper()).post(new Runnable() {
@Override
public void run() {
// Show the toast here
toast.show();
}
});
}
In both cases, the context is the application context, and I didn't see anything in the source that would cause one version to work, but the other not. Instead the latter has the same problems as if the Toast was shown directly in the IntentService: "Handler (android.os.Handler) {...} sending message to a Handler on a dead thread", Toast not disappearing, etc.
Why does the Toast have to be made on the main thread instead of just shown there?
1. Legacy = I don't think displaying error messages in Toasts is great UI, and I don't think services displaying messages to users directly is a good idea, but that's the code I was handed and I'd like to make it this little bit better.