我有一个Android应用程序,我想显示下载的天气数据的进度条。我将显示大约5个地方的天气预报。问题是当我想从响应头获取Content-Length时。日志总是显示-1(表示该字段未在URLConnection变量中设置)。
这是我正在使用的代码:
private class DownloadWeatherData extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... sUrl) {
try {
URL url = new URL("http://www.google.com/ig/api?weather=NY&hl=en&oe=utf-8");
URLConnection connection = url.openConnection();
int dataLenght = connection.getContentLength();
Log.d("ANDRO_ASYNC", "Data lenght: " + dataLenght);
InputStream input = new BufferedInputStream(url.openStream());
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
Log.d("ANDRO_ASYNC", ""+(int)((count)));
}
input.close();
} catch (Exception e) {
}
return null;
}
}
我该怎么办?或者是否有其他方式显示下载数据的进度?
答案 0 :(得分:2)
问题在于android的HttpUrlConnection
实现机制。这是what the official documentation says:
默认情况下,HttpURLConnection
的此实现请求服务器使用gzip压缩。由于getContentLength()
返回传输的字节数,因此您无法使用该方法来预测可以从getInputStream()
读取多少字节。相反,读取该流直到它耗尽:当read()
返回-1时。可以通过在请求标头中设置可接受的编码来禁用Gzip压缩:
urlConnection.setRequestProperty("Accept-Encoding", "identity");
答案 1 :(得分:1)
页面和其他文件通常不会带有Content-Length标头(作为“数据块”发送)。在这种情况下,通常浏览器不会显示百分比,而是显示永久动画栏(“// // // // //
”)。
当然,在了解网站的平均响应时间和传输客户端的缓慢时,您总是可以伪造它。