AsyncTask doInBackground 仅有时返回空指针异常

Posted

技术标签:

【中文标题】AsyncTask doInBackground 仅有时返回空指针异常【英文标题】:AsyncTask doInBackground returning a nullpointerexception only sometimes 【发布时间】:2012-02-18 07:08:09 【问题描述】:

收到此错误:

 java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1027)
Caused by: java.lang.NullPointerException
at com.Wahoo.BrowseListActivity$DownloadSite.doInBackground(BrowseListActivity.java:79)
at com.Wahoo.BrowseListActivity$DownloadSite.doInBackground(BrowseListActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
... 4 more

这是我的 AsyncTask...它仅在特定时间对某些用户崩溃...不知道为什么。也许他们在查询过程中失去了互联网连接?我在这里做错了什么?这是我的代码:

private class DownloadSite extends AsyncTask<String, Integer, String> 
        private HttpResponse response;
        private InputStream in;
        private Context context;
        private String html;
        private ProgressDialog progress;


        @Override
        protected String doInBackground(String... params) 

            in = null;

            String url = "aURLGOESHERE_BUTI'MCENSORING"                                 + params[0] + "";

            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet(url);
            HttpResponse response = null;

            try 
                response = client.execute(request);
             catch (ClientProtocolException e1) 
                // TODO Auto-generated catch block
                e1.printStackTrace();
             catch (IOException e1) 
                // TODO Auto-generated catch block
                e1.printStackTrace();
            

            try 
                in = response.getEntity().getContent();
             catch (IllegalStateException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
             catch (IOException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
             catch (Exception e) 

                e.printStackTrace();

            
            html = null;

            BufferedReader reader = null;
            try 
                reader = new BufferedReader(new InputStreamReader(in));
             catch (Exception e) 

                this.publishProgress();
                this.cancel(true);

                e.printStackTrace();
            

            StringBuilder str = new StringBuilder();
            String line = null;

            try 
                while ((line = reader.readLine()) != null) 
                    str.append(line);
                
             catch (IOException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            
            try 
                in.close();
             catch (IOException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            
            html = params[0] + str.toString();

            return html;

        

        @Override
        protected void onPreExecute() 

            progress = new ProgressDialog(BrowseListActivity.this);
            progress.setIndeterminate(true);
            progress.setMessage("Loading...");
            progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progress.show();
        

        @Override
        protected void onProgressUpdate(Integer... progress) 

            CharSequence text = "Connection interrupted...please try again";
            int duration = Toast.LENGTH_LONG;
            Toast toast = Toast.makeText(getApplicationContext(), text,
                    duration);
            toast.show();
        

        @Override
        protected void onPostExecute(String html) 
            progress.dismiss();

            Context context = BrowseListActivity.this;
            Intent stopViewer = new Intent(context, StopActivity.class);
            stopViewer.setData(Uri.parse(html + ""));
            context.startActivity(stopViewer);

        

    

【问题讨论】:

第 79 行是什么代码? 【参考方案1】:

您做错的一件事是在出现错误后继续执行doInBackground,导致无法有意义地继续。例如:

try 
    response = client.execute(request);
 catch (ClientProtocolException e1) 
    // TODO Auto-generated catch block
    e1.printStackTrace();
 catch (IOException e1) 
    // TODO Auto-generated catch block
    e1.printStackTrace();

如果这引发异常,response 将变为null,并且没有必要继续进行下去。您将在下一个代码块中生成NullPointerException。这不会是致命的,因为您在那里捕获了所有异常。但是,再进一步,这种模式会重复,您并没有捕获所有异常。

您应该提前退出,将null 作为字符串结果返回。然后您可以在onPostExecute 中测试null,并以优雅的方式让用户知道发生了什么。

【讨论】:

没错 - 任何 HTTP 调用都应考虑空响应。您可以在 doInBackground() 中进行空值检查,但如果您返回 null 并根据具体情况在 onProgressUpdate()onPostExecute() 中进行空值检查,它确实可以保持干净。 太棒了!谢谢,如果我发现这可行,我会调查并接受此回复。感谢您的反馈。

以上是关于AsyncTask doInBackground 仅有时返回空指针异常的主要内容,如果未能解决你的问题,请参考以下文章

无法让 doInBackground 在 AsyncTask 中工作

如何使 AsyncTask“doInBackground()”等待一个数组列表

如何在 doInBackground 的 AsyncTask 中显示 toast

AsyncTask doInBackground方法未调用

即使使用取消方法也无法取消 AsyncTask 中的 doInBackground 进程

AsyncTask.doInBackground 在 2.3 上没有被调用,在 4.0+ 上工作