无法在doInbackground()方法中执行AlertDialog
我在执行postexecute()上的AlertDialog时遇到问题。抛出这个异常 引起:java.lang.RuntimeException:无法在未调用Looper.prepare() 的线程内创建处理程序或者,当我放入AlertDialog.Builder时,它只是不起作用 请帮助。 同样在输入错误密码的情况下,该过程终止。我怎么能叫的情况下敬酒方法是将USENAME或密码无效 下面的代码片段无法在doInbackground()方法中执行AlertDialog
public void Login() {
// Toast.makeText(getBaseContext(), pass.getText() + " "
// +user.getText(),
// Toast.LENGTH_SHORT).show();
String url = "http://107.20.195.151/mcast_ws/" + "?user="
+ user.getText().toString() + "&password="
+ pass.getText().toString();
result = getHttpResponse(url);
}
String result;
private String getHttpResponse(String location) {
result = "";
URL url = null;
Log.d(LOGTAG, " " + "location " + location);
try {
url = new URL(location);
} catch (MalformedURLException e) {
Log.e(LOGTAG, " " + "error" + e.getMessage());
}
if (url != null) {
try {
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String inputLine;
int lineCount = 0;
while ((inputLine = in.readLine()) != null) {
result += inputLine.trim();
}
in.close();
connection.disconnect();
} catch (Exception e) {
Log.e(LOGTAG, " " + "IOError " + e.getMessage());
Toast.makeText(getBaseContext(), "No Internet Access",
Toast.LENGTH_SHORT);
}
} else {
Log.e(LOGTAG, " " + "url" + url);
}
return result;
}
class PostToTwitter extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
Login();
Log.d(LOGTAG, "Success");
Log.d(LOGTAG, result);
Log.d(LOGTAG, result.substring(0, 16).trim());
// Log.d(TweetActivity.getLogtag(),"Successfully Posted: " +
// params[0]);
return "success";
}
@Override
protected void onPostExecute(String r) {
// TODO Auto-generated method stub
super.onPostExecute(result);
String msg = "Login successful";
if (result.substring(0, 16).trim().equals(msg)) {
// System.out.println(result.substring(0, 16).trim());
Log.d(LOGTAG, " " + "Connection Test" + result);
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("Are you sure send this SMS?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//...Attach another thread event to send the sms
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
Log.e(LOGTAG, "Error detected 2");
AlertDialog alert = builder.create();
alert.show();
//return "success";
// Toast.makeText(getBaseContext(),
// "Login Succesful",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(),
"Login UnSuccesful. Check Username or password",
Toast.LENGTH_SHORT).show();
//return null;
}
// Toast.makeText(getApplicationContext(), result
// ,Toast.LENGTH_SHORT).show();
Log.e(LOGTAG, "Error detected");
/*
Intent i = new Intent("com.sms.subsahara.COMPOSESMS");
startActivity(i);
//Log.e(LOGTAG, " " + "error2");*/
}
}
在亚历克斯应用的建议,我修改了上面这个原代码,但仍得到一个错误。下面是从logcat的
E/AndroidRuntime( 326): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 326): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 326): at android.view.ViewRoot.setView(ViewRoot.java:472)
E/AndroidRuntime( 326): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime( 326): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 326): at android.app.Dialog.show(Dialog.java:239)
E/AndroidRuntime( 326): at com.sms.subsahara.WebMessengerActivity$PostToTwitter.onPostExecute(WebMessengerActivity.java:216)
E/AndroidRuntime( 326): at com.sms.subsahara.WebMessengerActivity$PostToTwitter.onPostExecute(WebMessengerActivity.java:1)
E/AndroidRuntime( 326): at android.os.AsyncTask.finish(AsyncTask.java:417)
E/AndroidRuntime( 326): at android.os.AsyncTask.access$300(AsyncTask.java:127)
E/AndroidRuntime( 326): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
E/AndroidRuntime( 326): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 326): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 326): at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime( 326): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 326): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 326): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime( 326): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime( 326): at dalvik.system.NativeStart.main(Native Method)
doInBackground
不与UI线程同步,这意味着您不能直接操作UI元素,从该方法中启动对话框等。修复很简单。只需将您的AlertDialog
代码移动到onPostExecute
方法(其中是与UI线程同步)。
当AsyncTask
s工作,请记住:
-
doInBackground
是为了进行潜在的昂贵的操作(网络访问,套接字连接,数据库查询等) -
onPostExecute
是为了做一些事情结果,如果你愿意(这种方法与UI线程同步,所以你可以直接操纵UI元素)
我想这是因为你登录()是的AsyncTask执行的内部,而不是在里面mainUI执行除外。可以将onPostExecute处理程序放在里面,回到主线程执行;也可以用onPostExecute UIThread:
runOnUiThread(new Runnable() {
@Override
public void run() {
Login();
}
});
我希望它能帮助你。
这个答案的第一句是正确的......但答案的其余部分是完全错误的。 (1)'onPostExecute'在UI线程上运行,因此创建一个'Runnable'并使用'runOnUiThread'执行代码只会让你放慢速度,(2)你是否确实要执行* Login *代码在'onPostExecute' ??这不符合使用'AsyncTask'的全部目的吗?! –
DoInBackground()只能在不同的t比主UI线程更重要。这是AsyncTask的重点。
有3种方式来发表您的结果到UI(几乎......到UI线程)
使用onPostExecute方法。你得到你传入的doInBackground方法的返回值,你可以用它做任何事情。 (我认为这与您的使用案例相符)。
如果您的任务正在进行,并且您希望在UI上发出少量突发信息(如进度条更新),请使用doInBackground方法中的publishProgress(...)然后将其传递给AsyncTask中的onProgressUpdate(...)方法,该方法将在UI线程上运行。
与2相似,但可以使用RunOnUiThread(...)方便的方法来抛出一个runnable在UI线程中运行。当你有多个匿名方法时,可能不会是最漂亮的代码,但它是快速和肮脏的方式来做到这一点。请注意,此方法可用于Activity类,而不是Context类,对于某些情况可能是交易断路器。
,因为Context的大多数子类甚至没有UI,所以实现'runOnUiMethod'没有什么意义。 –
@Alex洛克伍德
AsyncTask.doInBackground(Void..params)
是不适合很长时间和重复操作,更好的替代将是一个HandlerThread
。
原因:
在Android 3.2的,的AsyncTask在显著的方式改变了它的实现。从Android 3.2开始,AsyncTask 不会为AsyncTask中的每个实例创建线程,而是使用执行程序为单个后台线程上的所有AsyncTasks运行后台工作。这意味着每个AsyncTask线程必须一个接一个地运行。所以,举例来说,如果你有一个很长的AsyncTask线程(来自REST的图像获取器),我建议使用HandlerThread代替,因为运行线程的长任务可能会延迟整个链。
但
有可能并行使用线程池执行,而不是安全运行的AsyncTask,但我不知道确切的原因,程序员不推荐这样做的背后有几个原因与本文无关。但是如果你这样做,我会建议你做自己的线程,使用处理程序在必要时与主线程通信。
这个人是现货。只执行必须独立于后台UI线程完成的进程。 –
@ jack57,为什么谢谢你,善良的先生! –
但我认为你的意思是“操作”,而不是“过程”。好吧,我知道你是什么意思......但仅仅是为了技术...:P –