5

我的 android 应用程序中的代码存在问题。我以前没有处理过异步,我不确定如何调试这个问题。出于安全原因,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
4

2 回答 2

11

您可以使用runOnUiThreadorHanlder来显示来自非 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;

}
于 2013-06-07T18:33:17.467 回答
3

The doInBackground method in an AsyncTask should not perform any activity on the display (the UI) as it is specifically not on the UI thread. Although you can achieve this using the approach posted in @ρяσѕρєя K's answer, the very point of AsyncTask was to provide an easy mechanism for accessing the UI from a background thread in a structured manner.

When you call createMsg from within doInBackground, you break this paradigm. All UI actions in an AsyncTask should, in principle, be initiated from:

  • onPreExecute, which will be run before doInBackground
  • onPostExecute, which will be run once doInBackground has completed
  • onProgressUpdate, which will be run whenever publishProgress is called from doInBackground

The Android dev page includes a good usage example.

In your case, it looks like you should return a success or failure code from doInBackground which is picked up by onPostExecute; it should call createMsg if it has received a fail code.

于 2013-06-07T18:43:47.987 回答