为什么我用AsyncTask获取android.os.NetworkOnMainThreadException?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我用AsyncTask获取android.os.NetworkOnMainThreadException?相关的知识,希望对你有一定的参考价值。

我在AsynkTask中编写了网络操作代码时得到了android.os.NetworkOnMainThreadException。抛出这个例外有什么其他原因吗?

这是我的代码:

public class Background_confirmation extends AsyncTask<Void, Integer, Void> {
        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            progressDialog = ProgressDialog.show(Confirmation.this,
                    "Please wait...", "Retrieving data ...", true);
            try {
                HttpClient httpclient = new DefaultHttpClient();

                HttpPost httppost = new HttpPost(
                        "http://68.121.167.160/sip_chat_api/create_account.php?useralias="
                                + useralias + "&cntname=" + cntcode + "");
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                    is = entity.getContent();


            } catch (Exception e) {
                e.printStackTrace();
            }
            if (backgroung_flag == 1) {

            } else {
                if (is != null) {
                    try {
                        BufferedReader reader = new BufferedReader(
                                new InputStreamReader(is, "UTF-8"));
                        StringBuilder sb = new StringBuilder();
                        String line = null;
                        while ((line = reader.readLine()) != null) {
                            sb.append(line + "
");
                        }
                        is.close();

                        result = sb.toString();
                    } catch (Exception e) {
                        Log.e("log_tag",
                                "Error converting result " + e.toString());
                    }
                }

            }
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            if (progressDialog.isShowing()) {
                progressDialog.dismiss();
                // progressDialog.setCancelable(true);
            }
            super.onPostExecute(result);
        }

    }

我在OnCreate()中调用此类

new Background_confirmation().execute();

但它总是在Catch块中,并给我this例外LogCat 任何建议和想法都将得到赞赏。 谢谢

答案
public class Background_confirmation extends AsyncTask<Void, Integer, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = ProgressDialog.show(Confirmation.this, "Please wait...", "Retrieving data ...", true);

        }

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

            try {
                HttpClient httpclient = new DefaultHttpClient();

                HttpPost httppost = new HttpPost("http://68.121.167.160/sip_chat_api/create_account.php?useralias=" + useralias + "&cntname=" + cntcode + "");
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();

            } catch (Exception e) {
                e.printStackTrace();
            }
            if (backgroung_flag == 1) {

            } else {
                if (is != null) {
                    try {
                        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                        StringBuilder sb = new StringBuilder();
                        String line = null;
                        while ((line = reader.readLine()) != null) {
                            sb.append(line + "
");
                        }
                        is.close();

                        result = sb.toString();
                    } catch (Exception e) {
                        Log.e("log_tag", "Error converting result " + e.toString());
                    }
                }
            }
            return result;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            if (progressDialog.isShowing()) {
                progressDialog.dismiss();
                // progressDialog.setCancelable(true);
            }
        }
    }

您的代码应该像上面那样改变。你需要考虑的事情

  • 连接应该在doInBackground()内编码
  • 如果你想得到doInBackground()的结果,你必须把它带入onPostExecute()
  • 这意味着您必须在doInBackground()中返回一个String值,其中AsyncTask类的第三个参数也应该是String(这不是Wayne的答案)

在你的代码中,你正在调用除了“else”部分之外我们看不到的InputStream。如果您只使用InputStream,请确保代码始终到达else部分。

另一答案

您使用了错误的AsyncTask方法来放置与网络相关的代码。请把它移到doInBackground,因为onPreExecute发生在主线上。所以,发生了异常。详情是here

另一答案

将所有网络请求代码放在doInBackground中。 onPreExecuteonPostExecute将在UI线程(主要的thead)上运行,因此如果您在这两种方法上请求网络,您将获得一个例外。

public class Background_confirmation extends AsyncTask<Void, Integer, Void> {
    @Override
    protected void onPreExecute() {            
        progressDialog = ProgressDialog.show(Confirmation.this,
                "Please wait...", "Retrieving data ...", true);            

    }

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub

        try {
            HttpClient httpclient = new DefaultHttpClient();

            HttpPost httppost = new HttpPost(
                    "http://68.121.167.160/sip_chat_api/create_account.php?useralias="
                            + useralias + "&cntname=" + cntcode + "");
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
                is = entity.getContent();


        } catch (Exception e) {
            e.printStackTrace();
        }
        if (backgroung_flag == 1) {

        } else {
            if (is != null) {
                try {
                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(is, "UTF-8"));
                    StringBuilder sb = new StringBuilder();
                    String line = null;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line + "
");
                    }
                    is.close();

                    result = sb.toString();
                } catch (Exception e) {
                    Log.e("log_tag",
                            "Error converting result " + e.toString());
                }
            }

        }
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
            // progressDialog.setCancelable(true);
        }

    }

}

以上是关于为什么我用AsyncTask获取android.os.NetworkOnMainThreadException?的主要内容,如果未能解决你的问题,请参考以下文章

Android O:AsyncTask分析

具有自定义网格视图的 AsyncTask

AsyncTask的onPostExecute方法获取相同的参数

Android -- 关闭AsyncTask(异步任务)

取消执行AsyncTask的理想方法

在 AsyncTask 中使用 Picasso 从 URL 获取位图