-3

我有这段代码,但在我的 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();

            }

        });
4

4 回答 4

2

您需要将网络连接的一部分移动到单独的线程,最好使用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");
 }

}

于 2012-12-17T10:43:15.550 回答
1

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

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

于 2012-12-17T10:42:51.963 回答
1

来自官方文档:

只有针对 Honeycomb SDK 或更高版本的应用程序才会抛出此 (NetworkOnMainThreadException)。允许以早期 SDK 版本为目标的应用程序在其主事件循环线程上进行网络连接,但非常不鼓励这样做。

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

于 2012-12-17T10:44:34.270 回答
0

您正在尝试在 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/

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

于 2012-12-17T10:46:18.483 回答