1207

What does the following exception mean; how can I fix it?

This is the code:

Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);

This is the exception:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
     at android.os.Handler.<init>(Handler.java:121)
     at android.widget.Toast.<init>(Toast.java:68)
     at android.widget.Toast.makeText(Toast.java:231)
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
michael
  • 106,540
  • 116
  • 246
  • 346
  • 13
    check this library `compile 'com.shamanland:xdroid-toaster:0.0.5'`, it doesn't require `runOnUiThread()` or `Context` variable, all routine is gone! just invoke `Toaster.toast(R.string.my_msg);` here is the example: https://github.com/shamanland/xdroid-toaster-example – Oleksii K. Jul 17 '14 at 10:13
  • 180
    What a stupid error message! It could've been as simple as - can't call this from a non-UI thread as done when views are touched from a non-UI thread. – Dheeraj Bhaskar Aug 25 '14 at 15:49
  • 18
    For those who get the same exception message from different code: What the exception message means is that you are calling the code via a thread that has not prepared Looper. Normally it means you are not calling if from UI thread but you should (OP's case) - a normal thread does not prepare Looper, but UI thread always do. – Helin Wang Jul 14 '15 at 18:48
  • 1
    @OleksiiKropachov the implementation of the library you mentioned is very similar to doing a runOnUiThread(). – Helin Wang Jul 14 '15 at 19:21
  • 1
    yes, but it's a very useful wrapper – Oleksii K. Jul 14 '15 at 19:23
  • @DheerajBhaskar I wouldn't judge an expert developer's decision so quickly, it is stupid when you're not aware of the other scenarios this exception also covers, for me I had the same exception unrelated to the UI-Thread, the IABHandler that was given out by google itself for reference to use for in app purchase, was using new Handler without having Looper.getMainLooper(), for some "stupid" reasons ;) when I was using it normally I didn't have any problem, but when I used it inside an Executors thread pool, I got the same exception, never used any UI related method in there – Alireza Jamali Jun 24 '23 at 08:20

30 Answers30

978

You need to call Toast.makeText(...) from the UI thread:

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

This is copy-pasted from another (duplicate) SO answer.

Community
  • 1
  • 1
Jacob Marble
  • 28,555
  • 22
  • 67
  • 78
836

You're calling it from a worker thread. You need to call Toast.makeText() (and most other functions dealing with the UI) from within the main thread. You could use a handler, for example.

Look up Communicating with the UI Thread in the documentation. In a nutshell:

// Set this up in the UI thread.

mHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message message) {
        // This is where you do your work in the UI thread.
        // Your worker tells you in the message what to do.
    }
};

void workerThread() {
    // And this is how you call it from the worker thread:
    Message message = mHandler.obtainMessage(command, parameter);
    message.sendToTarget();
}

Other options:

You could use Activity.runOnUiThread(). Straightforward if you have an Activity:

@WorkerThread
void workerThread() {
    myActivity.runOnUiThread(() -> {
        // This is where your UI code goes.
    }
}

You could also post to the main looper. This works great if all you have is a Context.

@WorkerThread
void workerThread() {
    ContextCompat.getMainExecutor(context).execute(()  -> {
        // This is where your UI code goes.
    }
}

Deprecated:

You could use an AsyncTask, that works well for most things running in the background. It has hooks that you can call to indicate the progress, and when it's done.

It's convenient, but can leak contexts if not used correctly. It's been officially deprecated, and you shouldn't use it anymore.

EboMike
  • 76,846
  • 14
  • 164
  • 167
  • what about the original problem (it wasn't about AlertDialog)? – Ivan G. Jul 05 '11 at 18:29
  • 5
    Just adding my two cents to what Cleggy said. It would be preferable to provide a brief demonstration of what you mean (however contrived), as a coded example can often speak volumes for itself. – cdata Mar 01 '13 at 22:55
  • 5
    for a full technical answer see this http://prasanta-paul.blogspot.kr/2013/09/android-looper-and-toast-from.html – tony9099 Sep 26 '13 at 07:50
  • 3
    In almost all programming languages AFAIK which support GUI, if you update/change/display/interact with GUI directly, it should be done on the main thread of the program. – Ahmed Apr 18 '14 at 00:50
  • `(and most other functions dealing with the UI)` An example of a UI function usable from the background is `android.support.design.widget.Snackbar` -- its functionality is undiminished when not calling from the UI thread. – Scruffy Jul 31 '16 at 10:32
  • this answer is not much useful bit complicated – Anand Savjani May 31 '18 at 17:31
  • I wish the code was completed so I could see a full example. – Just The Highlights Feb 13 '19 at 20:07
  • I had a similar use case. "ContextCompat.getMainExecutor(context).execute(() -> { ..." did the trick. – AJW May 06 '21 at 01:48
461

UPDATE - 2016

The best alternative is to use RxAndroid (specific bindings for RxJava) for the P in MVP to take charge fo data.

Start by returning Observable from your existing method.

private Observable<PojoObject> getObservableItems() {
    return Observable.create(subscriber -> {

        for (PojoObject pojoObject: pojoObjects) {
            subscriber.onNext(pojoObject);
        }
        subscriber.onCompleted();
    });
}

Use this Observable like this -

getObservableItems().
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribe(new Observer<PojoObject> () {
    @Override
    public void onCompleted() {
        // Print Toast on completion
    }

    @Override
    public void onError(Throwable e) {}

    @Override
    public void onNext(PojoObject pojoObject) {
        // Show Progress
    }
});
}

----------------------------------------------------------------------------------------------------------------------------------

I know I am a little late but here goes. Android basically works on two thread types namely UI thread and background thread. According to android documentation -

Do not access the Android UI toolkit from outside the UI thread to fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help:

Activity.runOnUiThread(Runnable)  
View.post(Runnable)  
View.postDelayed(Runnable, long)

Now there are various methods to solve this problem.

I will explain it by code sample:

runOnUiThread

new Thread()
{
    public void run()
    {
        myactivity.this.runOnUiThread(new Runnable()
        {
            public void run()
            {
                //Do your UI operations like dialog opening or Toast here
            }
        });
    }
}.start();

LOOPER

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        Looper.prepare();

        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };

        Looper.loop();
    }
}

AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface. It performs the blocking operations in a worker thread and then publishes the results on the UI thread, without requiring you to handle threads and/or handlers yourself.

public void onClick(View v) {
    new CustomTask().execute((Void[])null);
}


private class CustomTask extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... param) {
        //Do some work
        return null;
    }

    protected void onPostExecute(Void param) {
        //Print Toast or open dialog
    }
}

Handler

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue.

Message msg = new Message();


new Thread()
{
    public void run()
    {
        msg.arg1=1;
        handler.sendMessage(msg);
    }
}.start();



Handler handler = new Handler(new Handler.Callback() {

    @Override
    public boolean handleMessage(Message msg) {
        if(msg.arg1==1)
        {
            //Print Toast or open dialog        
        }
        return false;
    }
});
mihirjoshi
  • 12,161
  • 7
  • 47
  • 78
  • 8
    This is _exactly_ what I was looking for. Especially the first example with `runOnUiThread` – Navin Nov 03 '13 at 02:19
  • 6
    Thanks, 5 years of Android programming and I never knew `View` also has methods `post(Runnable)` and `postDelayed(Runnable, long)`! So many Handlers in vain. :) – Fenix Voltres Apr 15 '15 at 09:13
  • for those who are confused by the Handler example: what is the thread that "new Handler(callback)" is bind to? It's bound to the thread that created the handler. – Helin Wang Jul 14 '15 at 18:44
  • 1
    Why is this **the best alternative**? – IgorGanapolsky Feb 02 '17 at 22:50
  • I usw doInBackground and I want to get a ArrayList back but I always get the error: Can't create handler inside thread that has not called Looper.prepare(). See this is my question https://stackoverflow.com/questions/45562615/looper-prepare-error-from-asyncthread-doinbackground?noredirect=1#comment78084303_45562615 but I can't get the solution from this answer here – WeSt Aug 08 '17 at 08:59
  • Years later, this was what I was looking for. Thank you. observeOn(AndroidSchedulers.mainThread()). – Zeek Aran Feb 14 '18 at 16:59
  • This is elegant to show the toast in different ways in non UI Thread @mjosh – anand krish Mar 29 '18 at 10:23
  • Instead of Print Toast or open dialog can I open a form or activity? – Jerry Abraham Dec 31 '18 at 08:11
  • My only regret is that I have but only one "up" vote to give.. +1000 – angryITguy Oct 14 '21 at 05:09
230

Toast.makeText() can only be called from Main/UI thread. Looper.getMainLooper() helps you to achieve it:

JAVA

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // write your code here
    }
});

KOTLIN

Handler(Looper.getMainLooper()).post {
        // write your code here
}

An advantage of this method is that you can run UI code without Activity or Context.

Ayaz Alifov
  • 8,334
  • 4
  • 61
  • 56
  • 3
    Thanks the other answers werent working for me. I am using a library sugar record to manage the persistence. And inside it i dont have the activity. But this works wonderfully – cabaji99 Oct 02 '17 at 20:38
  • @dcarl661, thanks for noticing. correction done – Ayaz Alifov Feb 18 '21 at 11:05
  • 1
    @AyazAlifov You say "it doesn't require Context", so what is mContext refering to? – akhil nair Jun 07 '21 at 11:23
  • 1
    Hi @akhilnair. Context is not required in order to run the android code by Main/UI thread. Main/UI thread can contain any code. In this specific example there is Toast method, which needs Context by its implementation. – Ayaz Alifov Jun 07 '21 at 17:42
  • Smallest and powerful answer. appreciate – AI Shakil Nov 17 '22 at 04:13
99

Try this, when you see runtimeException due to Looper not prepared before handler.

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

handler.postDelayed(new Runnable() {
  @Override
  public void run() {
  // Run your task here
  }
}, 1000 );
Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
Khulja Sim Sim
  • 3,469
  • 1
  • 29
  • 28
44

I ran into the same problem, and here is how I fixed it:

private final class UIHandler extends Handler
{
    public static final int DISPLAY_UI_TOAST = 0;
    public static final int DISPLAY_UI_DIALOG = 1;

    public UIHandler(Looper looper)
    {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg)
    {
        switch(msg.what)
        {
        case UIHandler.DISPLAY_UI_TOAST:
        {
            Context context = getApplicationContext();
            Toast t = Toast.makeText(context, (String)msg.obj, Toast.LENGTH_LONG);
            t.show();
        }
        case UIHandler.DISPLAY_UI_DIALOG:
            //TBD
        default:
            break;
        }
    }
}

protected void handleUIRequest(String message)
{
    Message msg = uiHandler.obtainMessage(UIHandler.DISPLAY_UI_TOAST);
    msg.obj = message;
    uiHandler.sendMessage(msg);
}

To create the UIHandler, you'll need to perform the following:

    HandlerThread uiThread = new HandlerThread("UIHandler");
    uiThread.start();
    uiHandler = new UIHandler((HandlerThread) uiThread.getLooper());

Hope this helps.

ChicoBird
  • 501
  • 4
  • 4
  • i tried to use your code but i lost and not sure how to call from `onCreate method` or from AsyncTask in my situation will you please post the entire code just to learn how things work? – Nick Kahn Feb 29 '12 at 03:41
  • 2
    Shouldn't that final line read `uiHandler = new UIHandler(uiThread.getLooper());` ? – Beer Me Sep 09 '13 at 16:42
40

Reason for an error:

Worker threads are meant for doing background tasks and you can't show anything on UI within a worker thread unless you call method like runOnUiThread. If you try to show anything on UI thread without calling runOnUiThread, there will be a java.lang.RuntimeException.

So, if you are in an activity but calling Toast.makeText() from worker thread, do this:

runOnUiThread(new Runnable() 
{
   public void run() 
   {
      Toast toast = Toast.makeText(getApplicationContext(), "Something", Toast.LENGTH_SHORT).show();    
   }
}); 

The above code ensures that you are showing the Toast message in a UI thread since you are calling it inside runOnUiThread method. So no more java.lang.RuntimeException.

sjain
  • 23,126
  • 28
  • 107
  • 185
24

that's what i did.

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Toast(...);
    }
});

Visual components are "locked" to changes from outside threads. So, since the toast shows stuff on the main screen that is managed by the main thread, you need to run this code on that thread. Hope that helps:)

eiran
  • 1,378
  • 15
  • 16
  • 1
    I used this same method. However, does this leave open the possibility of leaks, because the anonymous inner class of the Runnable will hold an implicit reference to the Activity? – Peter G. Williams May 27 '20 at 17:52
  • 1
    That's a fine point:) just use getApplicationContext() or something like that, to be on the safe side. altough i never had any problems with that code that i know of – eiran Jun 01 '20 at 13:04
22

I was getting this error until I did the following.

public void somethingHappened(final Context context)
{
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(
        new Runnable()
        {
            @Override
            public void run()
            {
                Toast.makeText(context, "Something happened.", Toast.LENGTH_SHORT).show();
            }
        }
    );
}

And made this into a singleton class:

public enum Toaster {
    INSTANCE;

    private final Handler handler = new Handler(Looper.getMainLooper());

    public void postMessage(final String message) {
        handler.post(
            new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(ApplicationHolder.INSTANCE.getCustomApplication(), message, Toast.LENGTH_SHORT)
                        .show();
                }
            }
        );
    }

}
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • Where are you using **Toaster**? In your first snippet it isn't used... – IgorGanapolsky Feb 02 '17 at 23:05
  • 1
    it was a convenience class I used like `Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));` (lengthy I know! we reduced this later), although I haven't been using toasts in a while – EpicPandaForce Feb 02 '17 at 23:12
  • So what does `ApplicationHolder.INSTANCE` evaluate to? – IgorGanapolsky Feb 03 '17 at 14:23
  • A static variable of `CustomApplication` set in `CustomApplication.onCreate()`, considering application always exists while the process exists, this context can be used globally – EpicPandaForce Feb 03 '17 at 14:23
15
 runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(mContext, "Message", Toast.LENGTH_SHORT).show();
            }
        });
Coldfin Lab
  • 361
  • 3
  • 8
  • 2
    This worked for me and I use lambda `runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });` – Black_Zerg Jan 06 '19 at 15:22
14

Wonderful Kotlin solution:

runOnUiThread {
    // Add your ui thread code here
}
jungledev
  • 4,195
  • 1
  • 37
  • 52
14

first call Looper.prepare() and then call Toast.makeText().show() last call Looper.loop() like:

Looper.prepare() // to be able to make toast
Toast.makeText(context, "not connected", Toast.LENGTH_LONG).show()
Looper.loop()
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203
11

This is because Toast.makeText() is calling from a worker thread. It should be call from main UI thread like this

runOnUiThread(new Runnable() {
      public void run() {
        Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
      }
 });
Biswajit Karmakar
  • 9,799
  • 4
  • 39
  • 41
8

The answer by ChicoBird worked for me. The only change I made was in the creation of the UIHandler where I had to do

HandlerThread uiThread = new HandlerThread("UIHandler");

Eclipse refused to accept anything else. Makes sense I suppose.

Also the uiHandler is clearly a class global defined somewhere. I still don't claim to understand how Android is doing this and what is going on but I am glad it works. Now I will proceed to study it and see if I can understand what Android is doing and why one has to go through all these hoops and loops. Thanks for the help ChicoBird.

Emre Yazici
  • 10,136
  • 6
  • 48
  • 55
Brian Reinhold
  • 2,313
  • 3
  • 27
  • 46
6

Coroutine will do it perfectly

CoroutineScope(Job() + Dispatchers.Main).launch {
                        Toast.makeText(context, "yourmessage",Toast.LENGTH_LONG).show()}
Abdelrahman Tareq
  • 1,874
  • 3
  • 17
  • 32
5

For Rxjava and RxAndroid User:

public static void shortToast(String msg) {
    Observable.just(msg)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(message -> {
                Toast.makeText(App.getInstance(), message, Toast.LENGTH_SHORT).show();
            });
}
Geng Jiawen
  • 8,904
  • 3
  • 48
  • 37
5

Java 8

new Handler(Looper.getMainLooper()).post(() -> {
    // Work in the UI thread

}); 

Kotlin

Handler(Looper.getMainLooper()).post{
    // Work in the UI thread
}

GL

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
Braian Coronel
  • 22,105
  • 4
  • 57
  • 62
4

I was running into the same issue when my callbacks would try to show a dialog.

I solved it with dedicated methods in the Activity - at the Activity instance member level - that use runOnUiThread(..)

public void showAuthProgressDialog() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mAuthProgressDialog = DialogUtil.getVisibleProgressDialog(SignInActivity.this, "Loading ...");
        }
    });
}

public void dismissAuthProgressDialog() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (mAuthProgressDialog == null || ! mAuthProgressDialog.isShowing()) {
                return;
            }
            mAuthProgressDialog.dismiss();
        }
    });
}
Gene Bo
  • 11,284
  • 8
  • 90
  • 137
2
Handler handler2;  
HandlerThread handlerThread=new HandlerThread("second_thread");
handlerThread.start();
handler2=new Handler(handlerThread.getLooper());

Now handler2 will use a different Thread to handle the messages than the main Thread.

Sumit Garai
  • 1,205
  • 8
  • 6
2

I got the same problem and this code is working fine for me now.
As an example this is my code to do a task in the background and UI thread.
Observe how the looper is used:

new Thread(new Runnable() {
    @Override
    public void run() {
    Looper.prepare();
                                
    // your Background Task here

    runOnUiThread(new Runnable() {
        @Override
        public void run() {

        // update your UI here      
                                
        Looper.loop();
        }
    });
    }
}).start();
zcoop98
  • 2,590
  • 1
  • 18
  • 31
Hasni
  • 187
  • 1
  • 10
1

To display a dialog or a toaster in a thread, the most concise way is to use the Activity object.

For example:

new Thread(new Runnable() {
    @Override
    public void run() {
        myActivity.runOnUiThread(new Runnable() {
            public void run() {
                myActivity.this.processingWaitDialog = new ProgressDialog(myActivity.this.getContext());
                myActivity.this.processingWaitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                myActivity.this.processingWaitDialog.setMessage("abc");
                myActivity.this.processingWaitDialog.setIndeterminate(true);
                myActivity.this.processingWaitDialog.show();
            }
        });
        expenseClassify.serverPost(
                new AsyncOperationCallback() {
                    public void operationCompleted(Object sender) {
                        myActivity.runOnUiThread(new Runnable() {
                            public void run() {
                                if (myActivity.this.processingWaitDialog != null 
                                        && myActivity.this.processingWaitDialog.isShowing()) {
                                    myActivity.this.processingWaitDialog.dismiss();
                                    myActivity.this.processingWaitDialog = null;
                                }
                            }
                        }); // .runOnUiThread(new Runnable()
...
Liwen Zhao
  • 545
  • 5
  • 9
1

Using lambda:

activity.runOnUiThread(() -> Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show());
Faisal Shaikh
  • 3,900
  • 5
  • 40
  • 77
0

Toast, AlertDialogs needs to run on UI thread, you can use Asynctask to use them properly in android development.but some cases we need to customize the time outs, so we use Threads, but in threads we cannot use Toast,Alertdialogs like we using in AsyncTask.So we need separate Handler for popup those.

public void onSigned() {
    Thread thread = new Thread(){
        @Override
        public void run() {
            try{
                sleep(3000);
                Message message = new Message();
                message.what = 2;
                handler.sendMessage(message);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    };
    thread.start();
}

in Above example i want to sleep my thread in 3sec and after i want to show a Toast message,for that in your mainthread implement handler.

handler = new Handler() {
       public void handleMessage(Message msg) {
           switch(msg.what){
              case 1:
              Toast.makeText(getActivity(),"cool",Toast.LENGTH_SHORT).show();
              break;
           }
           super.handleMessage(msg);
       }
};

I used switch case here, because if you need to show different message in same way, you can use switch case within Handler class...hope this will help you

GoRoS
  • 5,183
  • 2
  • 43
  • 66
Ashana.Jackol
  • 3,064
  • 28
  • 22
0

This usually happens when something on the main thread is called from any background thread. Lets look at an example , for instance.

private class MyTask extends AsyncTask<Void, Void, Void> {


@Override
protected Void doInBackground(Void... voids) {
        textView.setText("Any Text");
        return null;
    }
}

In the above example , we are setting text on the textview which is in the main UI thread from doInBackground() method , which operates only on a worker thread.

0

I had the same problem and I fixed it simply by putting the Toast in onPostExecute() override function of the Asynctask<> and it worked.

alibabaei12
  • 161
  • 1
  • 2
  • 9
0

You need to create toast on UI thread. Find the example below.

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

For displaying Toast message please refer to this article

0

Here is the solution for Kotlin using Coroutine:

Extend your class with CoroutineScope by MainScope():

class BootstrapActivity :  CoroutineScope by MainScope() {}

Then simply do this:

launch {
        // whatever you want to do in the main thread
    }

Don't forget to add the dependencies for coroutine:

org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.kotlinCoroutines}
org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.kotlinCoroutines}
Mehdi Satei
  • 1,225
  • 9
  • 26
0

Create Handler outside the Thread

final Handler handler = new Handler();

        new Thread(new Runnable() {
            @Override
            public void run() {
            try{
                 handler.post(new Runnable() {
                        @Override
                        public void run() {
                            showAlertDialog(p.getProviderName(), Token, p.getProviderId(), Amount);
                        }
                    });

                }
            }
            catch (Exception e){
                Log.d("ProvidersNullExp", e.getMessage());
            }
        }
    }).start();
0

Recently, I encounter this problem - It was happening because I was trying to call a function that was to do some UI stuff from the constructor. Removing the initialization from the constructor solved the problem for me.

giles
  • 85
  • 1
  • 9
-2

i use the following code to show message from non main thread "context",

@FunctionalInterface
public interface IShowMessage {
    Context getContext();

    default void showMessage(String message) {
        final Thread mThread = new Thread() {
            @Override
            public void run() {
                try {
                    Looper.prepare();
                    Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
                    Looper.loop();
                } catch (Exception error) {
                    error.printStackTrace();
                    Log.e("IShowMessage", error.getMessage());
                }
            }
        };
        mThread.start();
    }
}

then use as the following:

class myClass implements IShowMessage{

  showMessage("your message!");
 @Override
    public Context getContext() {
        return getApplicationContext();
    }
}
Mohamed.Abdo
  • 2,054
  • 1
  • 19
  • 12