无法在未调用 Looper.prepare() 的线程内创建处理程序 [英] Can't create handler inside thread that has not called Looper.prepare()

查看:25
本文介绍了无法在未调用 Looper.prepare() 的线程内创建处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下异常是什么意思;我该如何解决?

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

这是代码:

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)

推荐答案

您正在从工作线程调用它.您需要从主线程中调用 Toast.makeText()(以及大多数其他处理 UI 的函数).例如,您可以使用处理程序.

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.

在文档中查找与 UI 线程通信.简而言之:

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

其他选项:

您可以使用 Activity.runOnUiThread().如果您有 Activity,则直接:

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

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

您也可以发布到主循环播放器.如果您只有一个 Context,这很有效.

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.
    }
}

已弃用:

您可以使用 AsyncTask,它适用于大多数情况在后台运行.它具有钩子,您可以调用这些钩子来指示进度以及何时完成.

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.

这篇关于无法在未调用 Looper.prepare() 的线程内创建处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆