Android getContentLength return -1的另一种原因

关于URLConnection的getContentLength函数返还-1,网上几乎所有的说法,都是说因为启动了gzip 的缘故。解决方法也很简单:

urlConnection.setRequestProperty("Accept-Encoding", "identity");

但是我们注意到getContentLength函数的返还值是int类型的,如果要下载的文件大小超过int的表示范围会怎样?

今天就遇到这个问题了,我们的应用应用商店有一个2.2G的游戏(2449387037字节,int类型最大2147483648),总是提示下载失败。问题定位到获取文件长度这一行:

long len = connection.getContentLength();

len总是返还-1,获取不到文件长度,下载库便返回失败了。
既然getContentLength()不行,那有没有返还long的getContentLengthLong()函数呢?有是有,但是API24才支持啊,肯定不能用。

抓包看了一下,服务端返会的http header里面的'content-length'是正常的。那我们直接解析header的这个字段不就可以了,如下:

    /**
     * 从头文件得到下载内容的大小
     * @param urlConnection
     * @return
     */
    private long getContentLengthFromHeader(URLConnection urlConnection) {
        List values = urlConnection.getHeaderFields().get("content-Length");
        if (values != null && !values.isEmpty()) {

            String sLength = (String) values.get(0);

            if (sLength != null) {
                return Long.parseLong(sLength, 10);
            }
        }
        return -1;
    }

当调用系统的getContentLength函数失败时,再使用这个函数:

        // 开始下载
        long len = connection.getContentLength();

        //发现当文件长度大于int的表示范围时,connection.getContentLength()返回-1,所以改为从头部中获取
        if (len < 0) {
            len = getContentLengthFromHeader(connection);
        }

以上~

你可能感兴趣的:(Android getContentLength return -1的另一种原因)