下面的异常是什么意思;我该怎么解决呢?

这是代码:

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

这是例外:

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)

当前回答

当我的回调函数试图显示一个对话框时,我也遇到了同样的问题。

我用活动中的专用方法解决了这个问题-在活动实例成员级别-使用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();
        }
    });
}

其他回答

绝妙的Kotlin解决方案:

runOnUiThread {
    // Add your ui thread code here
}

我得到了同样的问题,这段代码为我工作很好。 作为一个例子,这是我的代码做一个任务在后台和UI线程。 观察如何使用套筒:

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

这通常发生在从任何后台线程调用主线程上的某些内容时。让我们看一个例子。

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


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

在上面的例子中,我们通过doInBackground()方法在主UI线程中的textview上设置文本,该方法只在工作线程上操作。

在执行以下操作之前,我一直得到这个错误。

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

并把它变成一个单例类:

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

}

Toast, alertdialog需要在UI线程上运行,你可以使用Asynctask在android开发中正确使用它们。但有些情况下,我们需要自定义超时,所以我们使用线程,但在线程中,我们不能使用Toast, alertdialog,就像我们在AsyncTask中使用的那样。我们需要单独的Handler来处理弹出这些。

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

在上面的例子中,我想睡我的线程在3秒后,我想显示一个吐司消息,在你的主线程实现处理程序。

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

我在这里使用了switch case,因为如果你需要以相同的方式显示不同的消息,你可以在Handler类中使用switch case…希望这对你有所帮助