java 无法在警报对话框线程上未调用 Looper.prepare() 的线程内创建处理程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38600372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't create handler inside thread that has not called Looper.prepare() on alert dialog thread
提问by Shino Rascal
i got an error on my splash activity when it checked internet connection and there's no internet .. it happened on my alert dialog, perhaps.
当我检查互联网连接并且没有互联网时,我的启动活动出现错误..它可能发生在我的警报对话框中。
java.lang.RuntimeException:
Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Dialog.<init>(Dialog.java:108)
at android.app.Dialog.<init>(Dialog.java:148)
at android.support.v7.app.AppCompatDialog.<init>(AppCompatDialog.java:43)
at android.support.v7.app.AlertDialog.<init>(AlertDialog.java:95)
at android.support.v7.app.AlertDialog$Builder.create(AlertDialog.java:927)
at com.example.study.Splash.checking(Splash.java:66)
at com.example.study.Splash.run(Splash.java:51)
i have tried runOnUiThread()
but it still not works ..
here's my splash code
我试过了,runOnUiThread()
但它仍然不起作用..这是我的启动代码
package com.example.study;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import com.example.study.helper.SessionManager;
import com.example.study.util.ConnectionDetector;
public class Splash extends AppCompatActivity {
private ConnectionDetector cd;
Boolean isInternetPresent = false;
protected SessionManager session;
private AlertDialog.Builder builder;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
builder = new AlertDialog.Builder(Splash.this);
session = new SessionManager(getApplicationContext());
cd = new ConnectionDetector(getApplicationContext());
builder.setTitle("No Connection");
builder.setMessage("Check Your Internet Connection.");
builder.setIcon(R.drawable.fail);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
/* TODO Auto-generated method stub */
dialog.dismiss();
}
});
Thread timer = new Thread(){
public void run(){
try {
sleep(2000);
} catch (Exception e) {
e.printStackTrace();
} finally {
checking();
}
}
};
timer.start();
}
public void checking() {
isInternetPresent = cd.isConnectingToInternet();
if(isInternetPresent) {
session.checkLogin();
finish();
} else {
builder.create().show();
finish();
}
}
}
采纳答案by Jahnold
In Android the Looper
is a queue system that runs a message loop. By default a Thread does not have a Looper associated with it when you create it. As such when your AlertDialog tries to use the message queue it crashes.
在 Android 中,这Looper
是一个运行消息循环的队列系统。默认情况下,创建线程时,线程没有与之关联的 Looper。因此,当您的 AlertDialog 尝试使用消息队列时,它会崩溃。
You couldcreate a Looper in your new thread however you should really be using an AlertDialog on the main thread. To do this you can use postDelayed
method of a Handler
:
您可以在新线程中创建一个 Looper,但是您确实应该在主线程上使用 AlertDialog。为此,您可以使用 a 的postDelayed
方法Handler
:
new Handler().postDelayed(
new Runnable() {
@Override
public void run() {
checking();
}
},
2000
);
in your onCreate
method
在你的onCreate
方法中
回答by RabidMutant
As a refinement to the earlier question, I would probably do the following since network activity on the UI thread is also a bad idea:
作为对先前问题的改进,我可能会执行以下操作,因为 UI 线程上的网络活动也是一个坏主意:
Create a Handler in the onCreate():
在 onCreate() 中创建一个处理程序:
mHandler = new Handler();
And still run checking() in it's own thread, but change it slightly:
并且仍然在它自己的线程中运行检查(),但稍微改变它:
public void checking() {
isInternetPresent = cd.isConnectingToInternet();
if(isInternetPresent) {
session.checkLogin();
finish();
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
builder.create().show();
finish();
});
}
}
This way, UI us done on the UI thread and network is done in another thread.
这样,UI 我们在 UI 线程上完成,而网络在另一个线程中完成。