当我尝试将setRequestProperty设置为HttpURLConnection时,Android会出错

时间:2015-06-15 05:48:38

标签: java android

我写了简单的下载管理器,我试图为所有下载设置RESUME。谷歌后如何做到这一点。我知道连接必须FATAL EXCEPTION: Thread-882 java.lang.IllegalStateException: Cannot set request property after connection is made at libcore.net.http.HttpURLConnectionImpl.setRequestProperty(HttpURLConnectionImpl.java:510) ,但我的代码不起作用,我收到此错误:

URL url = new URL(downloadPath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

final int fileSize = connection.getContentLength();

File file = new File(filepath);
if (file.exists() && fileSize == file.length()) {
    return;
} else if (file.exists()) {
    connection.setRequestProperty("Range", "bytes="+(file.length())+"-");
}else
    connection.setRequestProperty("Range", "bytes=" + downloadedSize + "-");

connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();

我的代码是:

setRequestProperty

如何解决此问题并正确设置Func连接?

3 个答案:

答案 0 :(得分:1)

问题是,在您致电connection.getContentLength()之前,您正在呼叫setRequestProperty()。内容长度仅在发出请求后可用,此时您无法设置请求属性...

目前还不完全清楚你要做的是什么,但一种选择是使用HEAD请求来获取内容长度,然后再做一个单独的请求需要获得一部分数据。请注意,当然,内容长度可能会在请求之间发生变化。

但是,我实际上建议在下载管理器中的某处保留更多元数据 - 这样当您第一次开始下载数据时,您会记录总大小,这样您就不需要制作{{1恢复时请求 - 您可以从本地信息中告诉您是否已经下载了文件。 (这在内容更改方面存在同样的问题,但这是另一回事。)

答案 1 :(得分:1)

我遇到的错误与OP相同。

<强> WHY 问题是,当您尝试将params设置为恢复下载的请求时,您必须与Http断开连接。

当您调用方法connection.getContentLenght();时,会发生connection.connect();,所以如果您尝试将属性设置为连接,则会收到提及的错误。

<强> FIX 我做的是在调用方法long totalFileSize = connection.getContentLength();

后关闭了与Http的连接

connection.disconnect() //与http断开连接

之后,您可以设置您想要连接的参数,并在需要时调用connection.connect()

提示 在我的特定情况下,我试图下载文件并需要支持可恢复的下载,所以我做的就是:

  • 检查文件是否存在。
  • 如果文件存在,则获取文件的长度:

    long bytesDownloaded = file.getLenght();

  • 使用此长度将其设置为连接,以便它可以从其暂停的字节中恢复。

  • 将字节写入文件末尾。

答案 2 :(得分:0)

  1. 您应该在getContentLength()
  2. 之前设置属性
  3. 如果设置范围等于存在文件长度,则在调用getContentLength()时将收到剩余字节,因此如果内容长度等于&#34; 0&#34;这意味着文件已完全下载。
  4. 但是如果你想建立一个下载管理器,@ Jon Skeet的方法是合理的。

    编辑:

      

    public abstract long getContentLength()

         

    在API级别1中添加说明内容的长度(如果已知)。

         

    返回内容的字节数,如果是,则返回负数   未知。如果内容长度已知但超过Long.MAX_VALUE,则a   返回负数。