无法在未调用Looper.prepare()的线程内创建处理程序
以下例外是什么意思; 我该如何解决它?
这是代码:
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的大多数其他函数)。 例如,您可以使用处理程序。
查阅文档中的UI线程通信。 简而言之:
// 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();
}
其他选项:
你可以使用一个AsyncTask,它适用于在后台运行的大多数事情。 它具有可以调用的钩子来指示进度以及完成时间。
你也可以使用Activity.runOnUiThread()。
您需要从UI线程调用Toast.makeText(...)
:
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
这是从另一个(重复)SO回答复制粘贴。
更新 - 2016年
最好的选择是使用RxAndroid
(用于特异性结合RxJava
)为P
在MVP
人主FO数据。
从现有方法返回Observable
开始。
private Observable<PojoObject> getObservableItems() {
return Observable.create(subscriber -> {
for (PojoObject pojoObject: pojoObjects) {
subscriber.onNext(pojoObject);
}
subscriber.onCompleted();
});
}
像这样使用这个Observable -
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
}
});
}
-------------------------------------------------- -------------------------------------------------- ------------------------------
我知道我有点晚了,但在这里。 Android基本上适用于两种线程类型,即UI线程和后台线程 。 根据android文档 -
不要从UI线程外部访问Android UI工具包来解决这个问题,Android提供了几种方法从其他线程访问UI线程。 以下是可以提供帮助的方法列表:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
现在有各种方法来解决这个问题。
我将通过代码示例来解释它:
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
用于为线程运行消息循环的类。 线程默认没有与它们相关的消息循环; 创建一个,在要运行循环的线程中调用prepare(),然后循环()使其处理消息,直到循环停止。
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允许您在用户界面上执行异步工作。 它在工作线程中执行阻塞操作,然后将结果发布到UI线程上,而无需您自己处理线程和/或处理程序。
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允许您发送和处理与线程的MessageQueue关联的Message和Runnable对象。
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;
}
});
链接地址: http://www.djcxy.com/p/67687.html
上一篇: Can't create handler inside thread that has not called Looper.prepare()
下一篇: getting the screen density programmatically in android?