java 执行 doInBackground() android 时发生错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16990620/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 00:38:09  来源:igfitidea点击:

an error occured while executing doInBackground() android

javaandroidandroid-asynctask

提问by JohnHoulderUK

I am facing an issue with my code in my android app. I've not dealt with Async before and I'm unsure of how to debug the issue. For security reasons, the URL has been replaced.

我的 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;
        }
    }
}

Thanks in advance!

提前致谢!

EDIT: createMsg creates an android alert box.

编辑:createMsg 创建一个 android 警报框。

Error:

错误:

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.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.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.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

回答by ρяσ?ρ?я K

you can use runOnUiThreador Hanlderfor showing Toast or Alertbox from non UI Thread(in your case from doInBackground). do it as:

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

}

回答by Neil Townsend

The doInBackgroundmethod in an AsyncTaskshould 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.

中的doInBackground方法AsyncTask不应在显示(UI)上执行任何活动,因为它特别不在 UI 线程上。尽管您可以使用@ρяσ?ρ?я K 的回答中发布的方法来实现这一点,但 AsyncTask 的重点是提供一种简单的机制,用于以结构化的方式从后台线程访问 UI。

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

当你createMsg从内部调用时doInBackground,你打破了这个范式。AsyncTask 中的所有 UI 操作原则上应该从以下位置启动:

  • onPreExecute, which will be run before doInBackground
  • onPostExecute, which will be run once doInBackgroundhas completed
  • onProgressUpdate, which will be run whenever publishProgressis called from doInBackground
  • onPreExecute,这将在之前运行 doInBackground
  • onPostExecute, 将在doInBackground完成后运行
  • onProgressUpdate, 每当publishProgress被调用时都会运行doInBackground

The Android dev pageincludes a good usage example.

Android开发人员网页包括了良好的使用示例。

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

在您的情况下,您似乎应该返回一个成功或失败代码,doInBackground从中获取onPostExecute; createMsg如果它收到失败代码,它应该调用。