【问题标题】:Load image from url in Android, only if small从 Android 中的 url 加载图像,只有在很小的情况下
【发布时间】:2010-07-25 10:56:02
【问题描述】:

我正在使用BitmapFactory.decodeStream 从 Android 中的 url 加载图像。我只想下载一定大小以下的图像,我目前正在使用getContentLength 来检查这一点。

但是,有人告诉我getContentLength 并不总是提供文件的大小,在这种情况下,我想在知道文件太大后立即停止下载。这样做的正确方法是什么?

这是我当前的代码。如果getContentLength 没有提供答案,我目前返回 null。

HttpGet httpRequest = new HttpGet(new URL(urlString).toURI());
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpClient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity); 
final long contentLength = bufHttpEntity.getContentLength();
if ((contentLength >= 0 && (maxLength == 0 || contentLength < maxLength))) {
    InputStream is = bufHttpEntity.getContent();
    Bitmap bitmap = BitmapFactory.decodeStream(is);
    return new BitmapDrawable(bitmap);
} else {
    return null;
}

【问题讨论】:

    标签: android url bitmap httpclient httprequest


    【解决方案1】:

    1 .您也可以尝试这种方法。我相信它不会下载大文件的内容

    HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();  
    int length=connection.getContentLength(); 
    
    if(length<max){  
      InputStream is = connection.getInputStream();  
      BitmapFactory.decodeStream(is,null,null);
    }
    

    这只是一个示例,您还可以添加检查 -1 和其他任何内容。 这种方法等同于您所做的。这只是您尝试的另一种选择。我只知道 HttpURLConnection 在您开始从流中读取内容之前不会获取内容。所以这段代码不会下载大图像。我真的不知道 HttpClient 是否也这样做。

    2 。为什么实际上你想跳过更大的文件。如果您在解码期间担心 OutOfMemory 可以看看这个Strange out of memory issue while loading an image to a Bitmap object。如果您应用 inSampleSize,您甚至可以下载大图像。对于较大的图像,延迟会更大,但内存消耗会很低。我在这里 Lazy load of images in ListView 发布了我的 ListView 示例。它在 ListView 中显示图像。有不同大小的图像。不是很大的图像,但无论如何。

    【讨论】:

    • 该代码无法正确处理 getContentLength 返回 -1 的情况。另外,这不是我正在做的更简单的版本吗?我想跳过大文件,因为这个逻辑是针对 ListView 的每个项目执行的。
    • 更新了我的帖子,提供更多说明。
    • 比起OutOfMemory,我更关心滚动速度。正如您所提到的,如果您缩小大图像,延迟会更大。
    • 图像大小不会影响滚动速度,因为图像下载/解码应该在后台线程中处理。看看我的 LazyList 示例 - 它完全一样。
    【解决方案2】:

    您应该使用 HttpHead 发出 HEAD 请求,这与 GET 类似,但只会返回标头。如果内容长度令人满意,那么您可以发出 GET 请求来获取内容。

    大多数服务器应该可以毫无问题地处理 HEAD 请求,但有时应用服务器不会期待它并且会抛出错误。只是需要注意的事情。

    UPDATE 以为我也会尝试回答您的实际问题。在将数据传递给 BitmapFactory 之前,您可能必须将数据读入中间字节缓冲区。

    InputStream is = bufHttpEntity.getContent();
    ByteArrayOutputStream bytes = ByteArrayOutputStream();
    byte[] buffer = new byte[128];
    int read;
    int totalRead = 0;
    while ((read = is.read(buffer)) > 0) {
       totalRead += read;
       if (totalRead > TOO_BIG) {
         // abort download. close connection
         return null;
       }
       bytes.write(buffer, 0 read);
    }
    

    不相关,但记得在使用后总是在实体上调用consumeContent(),以便HttpClient可以重用连接。

    【讨论】:

    • 我知道这并不能解决您的服务器不提供 Content-Length 的问题,但我认为您使用 HttpGet 的地方可能会获取您想要的内容或不是。如果它只在您从流中读取时得到它,请忽略我的回答!
    • 谢谢尼克。我不知道使用 HttpHead 是否会节省带宽,但在我的特殊情况下,我更喜欢将 http 请求保持在最低限度。
    【解决方案3】:

    这是一个从服务器加载图像的好例子。 blog.sptechnolab.com/2011/03/04/android/android-load-image-from-url/.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-27
      • 2015-11-29
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多