我的Android应用程序中的代码存在问题。我以前没有处理Async,我不确定如何调试问题。出于安全原因,URL已被替换。
class checkLogin extends AsyncTask<String, Void, Boolean> {
protected Boolean doInBackground(String... params) {
String urlStr = "http://example.com/api/?username=" + params[0] + "&password=" + params[1] + "&action=checkLogin";
try{
URL url = new URL(urlStr);
HttpURLConnection connection= (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.connect();
BufferedReader reader= new BufferedReader(new InputStreamReader(connection.getInputStream()));
String output = "";
String str;
while ((str= reader.readLine()) != null) {
output += "\r\n" + str;
}
createMsg(output,"Debug");
return true;
}catch(Exception e){
createMsg("Encountered an error. Report this problem to the development department with steps to reproduce","Fatal Error");
return false;
}
}
}
提前致谢!
编辑: createMsg创建一个android警告框。
错误:
06-07 18:19:35.066: E/AndroidRuntime(1206): FATAL EXCEPTION: AsyncTask #1
06-07 18:19:35.066: E/AndroidRuntime(1206): java.lang.RuntimeException: An error occured while executing doInBackground()
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-07 18:19:35.066: E/AndroidRuntime(1206): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
06-07 18:19:35.066: E/AndroidRuntime(1206): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
06-07 18:19:35.066: E/AndroidRuntime(1206): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-07 18:19:35.066: E/AndroidRuntime(1206): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
06-07 18:19:35.066: E/AndroidRuntime(1206): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
06-07 18:19:35.066: E/AndroidRuntime(1206): at java.lang.Thread.run(Thread.java:856)
06-07 18:19:35.066: E/AndroidRuntime(1206): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.os.Handler.<init>(Handler.java:197)
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.os.Handler.<init>(Handler.java:111)
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.app.Dialog.<init>(Dialog.java:107)
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.app.AlertDialog.<init>(AlertDialog.java:114)
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.app.AlertDialog$Builder.create(AlertDialog.java:931)
06-07 18:19:35.066: E/AndroidRuntime(1206): at com.unrealonline.timesheet.MainActivity.createMsg(MainActivity.java:55)
06-07 18:19:35.066: E/AndroidRuntime(1206): at com.unrealonline.timesheet.MainActivity$checkLogin.doInBackground(MainActivity.java:79)
06-07 18:19:35.066: E/AndroidRuntime(1206): at com.unrealonline.timesheet.MainActivity$checkLogin.doInBackground(MainActivity.java:1)
06-07 18:19:35.066: E/AndroidRuntime(1206): at android.os.AsyncTask$2.call(AsyncTask.java:287)
06-07 18:19:35.066: E/AndroidRuntime(1206): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
06-07 18:19:35.066: E/AndroidRuntime(1206): ... 4 more
答案 0 :(得分:11)
您可以使用runOnUiThread
或Hanlder
来显示来自非UI线程的Toast或Alertbox(在您的情况下来自doInBackground
)。这样做:
try{
//.....your code here...
while ((str= reader.readLine()) != null) {
output += "\r\n" + str;
}
Your_Current_Activity.this.runOnUiThread(new Runnable() {
public void run() {
createMsg(output,"Debug"); // show message here
}
});
return true;
}catch(Exception e){
//use runOnUiThread for showing Alert here....
return false;
}
答案 1 :(得分:3)
doInBackground
中的AsyncTask
方法不应在显示(UI)上执行任何活动,因为它特别不在UI线程上。虽然您可以使用@ρяσѕρєяK的答案中公布的方法来实现这一点,但AsyncTask的重点是提供一种从结构化方式从后台线程访问UI的简单机制。
当您从createMsg
内拨打doInBackground
时,您就打破了这种模式。原则上,AsyncTask中的所有UI操作都应该从以下开始:
onPreExecute
,将在doInBackground
onPostExecute
,将在doInBackground
完成后运行onProgressUpdate
,只要publishProgress
doInBackground
,就会运行
Android dev page包含一个很好的用法示例。
在您的情况下,看起来您应该从doInBackground
返回onPostExecute
获取的成功或失败代码;如果收到失败代码,它应该调用createMsg
。