【问题标题】:Error networkonmainthreadexception null错误 networkonmainthreadexception null
【发布时间】:2012-12-17 10:40:17
【问题描述】:

我有此代码,但在我的 Android Emulator 4.2 中出现以下错误:networkonmainthreadexception null

我是 Android 新手,这是我的第一个应用程序,我有一个网络视图,需要下载 PDF 并保存在 SD 卡中。

这是我的代码:

browser.setDownloadListener(new DownloadListener()
        {
            public void onDownloadStart(final String url, String userAgent, String contentDisposition, String mimetype, long contentLength)
            {               
                AlertDialog.Builder builder = new AlertDialog.Builder(WebViewdemoActivity.this);
                builder.setTitle("Descarga");
                builder.setMessage("¿Desea guardar el fichero en su tarjeta SD?");
                builder.setCancelable(false).setPositiveButton("Aceptar", new DialogInterface.OnClickListener()
                {
                    public void onClick(DialogInterface dialog, int id)
                    {
                        descargar(url);
                    }

                }).setNegativeButton("Cancelar", new DialogInterface.OnClickListener()
                {
                    public void onClick(DialogInterface dialog, int id)
                    {
                        dialog.cancel();
                    }
                });
                builder.create().show();                


            }

            private void descargar(final String url)
            {
           String resultado ="";

                //se obtiene el fichero con Apache HttpClient, API recomendada por Google
                HttpClient httpClient = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url);
                InputStream inputStream = null;
                try
                {
                    HttpResponse httpResponse = httpClient.execute(httpGet);

                    BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpResponse.getEntity());

                    inputStream = bufferedHttpEntity.getContent();

                    //se crea el fichero en el que se almacenará
                    String fileName = android.os.Environment.getExternalStorageDirectory().getAbsolutePath() + "/webviewdemo";
                    File directorio = new File(fileName);
                    File file = new File(directorio, url.substring(url.lastIndexOf("/")));
                    //asegura que el directorio exista
                    directorio.mkdirs();                    

                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

                    byte[] buffer = new byte[1024];

                    int len = 0;
                    while (inputStream.available() > 0 && (len = inputStream.read(buffer)) != -1)
                    {
                        byteArrayOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.write(byteArrayOutputStream.toByteArray());
                    fileOutputStream.flush();
                    resultado = "guardado en : " + file.getAbsolutePath();
                }
                catch (Exception ex)
                {
                    resultado = ex.getClass().getSimpleName() + " " + ex.getMessage();
                }
                finally
                {
                    if (inputStream != null)
                    {
                        try
                        {
                            inputStream.close();
                        }
                        catch (IOException e)
                        {

                        }
                    }
                }

                AlertDialog.Builder builder = new AlertDialog.Builder(WebViewdemoActivity.this);
                builder.setMessage(resultado).setPositiveButton("Aceptar", null).setTitle("Descarga");
                builder.show();

            }

        });

【问题讨论】:

  • 不要在主线程中调用网络操作,在后台线程中进行!
  • 你应该在线程或异步任务中调用网络。从 3.0 开始,主线程不支持网络调用。

标签: android networkonmainthread


【解决方案1】:

您需要将部分网络连接移动到单独的线程,最好使用AsyncTask..

例如:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
 protected Long doInBackground(URL... urls) {
     int count = urls.length;
     long totalSize = 0;
     for (int i = 0; i < count; i++) {
         totalSize += Downloader.downloadFile(urls[i]);
         publishProgress((int) ((i / (float) count) * 100));
         // Escape early if cancel() is called
         if (isCancelled()) break;
     }
     return totalSize;
 }

 protected void onProgressUpdate(Integer... progress) {
     setProgressPercent(progress[0]);
 }

 protected void onPostExecute(Long result) {
     showDialog("Downloaded " + result + " bytes");
 }

}

【讨论】:

    【解决方案2】:

    您需要在辅助线程上执行网络操作,要么创建一个新线程,要么使用更合适的方法:AsyncTask。 http://developer.android.com/reference/android/os/AsyncTask.html

    这将在另一个线程上执行操作,而不是锁定主/UI 线程。

    【讨论】:

      【解决方案3】:

      来自官方文档:

      只有针对 Honeycomb SDK 或更高版本的应用程序才会抛出此 (NetworkOnMainThreadException)。允许针对早期 SDK 版本的应用程序执行 在他们的主事件循环线程上联网,但它很重 气馁。

      链接:http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

      【讨论】:

        【解决方案4】:

        您正在尝试在 Android 4.0 不支持的主线程上连接互联网。您应该在 AysnchTask 中连接到互联网。有关更多详细信息,您可以从以下教程中获取帮助。

        http://developer.android.com/reference/android/os/AsyncTask.html

        http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/

        我相信你会从中得到一些东西。试试吧!

        【讨论】:

          猜你喜欢
          • 2014-06-27
          • 2014-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-25
          • 2012-08-09
          相关资源
          最近更新 更多