Can't create handler inside thread that has no

2018-12-31 00:21发布

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)

20条回答
余生无你
2楼-- · 2018-12-31 00:47

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

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

handler.postDelayed(new Runnable() {
  @override
  void run() {
  // Run your task here
  }
}, 1000 );
查看更多
人间绝色
3楼-- · 2018-12-31 00:47

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();
        }
    });
}
查看更多
永恒的永恒
4楼-- · 2018-12-31 00:47

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();
    }
}
查看更多
临风纵饮
5楼-- · 2018-12-31 00:52

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

查看更多
人气声优
6楼-- · 2018-12-31 00:55

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();
                }
            }
        );
    }

}
查看更多
步步皆殇っ
7楼-- · 2018-12-31 00:56

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();
            });
}
查看更多
登录 后发表回答