【问题标题】:How and why not run a "timeout" on URLConnection (DownloadFile)?如何以及为什么不在 URLConnection (DownloadFile) 上运行“超时”?
【发布时间】:2013-09-30 08:40:06
【问题描述】:

我有一个允许下载文件的异步方法。 如果在下载过程中,我将删除连接(wifi 或 3g)永远不会发生超时。

始终停留在下一个循环等待返回连接:

while ((count = input.read(data)) != -1) {
        System.out.println("state 5");
        total += count;
        publishProgress((int) (total * 100 / fileLength));
        output.write(data, 0, count);
}

我愿意:

  private class DownloaderFile extends AsyncTask<String, Integer, String> {
        @Override
        protected String doInBackground(String... params) {
            ...
            try{
                URLConnection connection = urlFinal.openConnection();
                connection.setConnectTimeout(TIMEOUT_VALUE);
                connection.setReadTimeout(TIMEOUT_VALUE);
                connection.connect();
                int fileLength = connection.getContentLength();

                InputStream input = new BufferedInputStream(urlFinal.openStream());

                OutputStream output = new FileOutputStream(folder + params[0]);

                byte data[] = new byte[1024];
                long total = 0;
                int count;

                while ((count = input.read(data)) != -1) {
//always wait here
                    System.out.println("state 5");
                    total += count;
                    publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();
            } catch (SocketTimeoutException e) {
                System.out.println("TIMEOUT!!! " + TIMEOUT_VALUE + " elapsed.");
                callback.onDownloadEnd(DOWNLOAD_ERROR);
            }
            ...
        }
        ...

【问题讨论】:

标签: java android timeout urlconnection connection-timeout


【解决方案1】:

这不是一个很好的解决方案,但它确实有效。当我想到另一个解决方案时......

while ((count = input.read(data)) != -1) {
     if (!isInternet(context)){
        callback.onDownloadEnd(DOWNLOAD_ERROR);
         return "error";
     }
     total += count;
     publishProgress((int) (total * 100 / fileLength));
     output.write(data, 0, count);
}

【讨论】:

    【解决方案2】:

    无论是什么原因,我都在猜测当 3g/wifi 不再可用时,从套接字读取的线程被阻塞了。

    您可以在此处采用的一种方法是在单独的线程上执行套接字读取,并使用Thread.join(long millis) 方法等待最长毫秒以完成。

    Thread t = new Thread(new Runnable() {
                 void run() {
                   ...
                   while ((count = input.read(data)) != -1) {
                     ...
                   }
                   ...
                 }
               }).start();
    
    t.join(TIMEOUT_VALUE); // will wait here until either the thread t is done or times out
    

    【讨论】:

    • 这不是一个解决方案,取决于连接速度,文件可能需要一些时间来下载,我不知道时间因此没用。
    • 因此你为什么还要担心你的代码会超时?这里的前提是,如果下载时间比您预期的要长,您预计会发生超时吗?
    【解决方案3】:

    我怀疑 SocketTimeoutException 是要查找的错误异常,因为在您的测试中建立了正确的连接,如果您将其更改为异常怎么办?只是看看这是否有帮助。

    我可以从:How to set HttpResponse timeout for Android in Java 看到我弄错了。

    从我链接的信息中我发现您可能需要设置:

      // Set the default socket timeout (SO_TIMEOUT) 
      // in milliseconds which is the timeout for waiting for data.
      int timeoutSocket = 5000;
      HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    

    【讨论】:

    • 我试过了:... } catch (Exception e) { System.out.println("error timeout"); callback.onDownloadEnd(DOWNLOAD_ERROR); } 但是那个异常不起作用。
    • 该解决方案是使用http请求,我在其他情况下使用它并且超时工作完美。问题出在上面的 URLConnection 代码中,它允许下载文件(例如 MP3)。
    猜你喜欢
    • 2012-07-19
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 2011-09-25
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    相关资源
    最近更新 更多