2013-07-15 43 views
6

我想显示一个列表视图与很多(远程)图像。我正在尝试使用抽签。排球和位图缓存

排球有些作品,但不够好。在ImageLoader.get凌空具有下面的代码段:

final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight); 

    // Try to look up the request in the cache of remote images. 
    Bitmap cachedBitmap = mCache.getBitmap(cacheKey); 
    if (cachedBitmap != null) { 
     // Return the cached bitmap. 
     ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null); 
     imageListener.onResponse(container, true); 
     return container; 
    } 

然而,getCacheKey产生一个关键是这样的:

/** 
* Creates a cache key for use with the L1 cache. 
* @param url The URL of the request. 
* @param maxWidth The max-width of the output. 
* @param maxHeight The max-height of the output. 
*/ 
private static String getCacheKey(String url, int maxWidth, int maxHeight) { 
    return new StringBuilder(url.length() + 12).append("#W").append(maxWidth) 
      .append("#H").append(maxHeight).append(url).toString(); 
} 

即它附加一些像的宽度和高度与键“元数据”。

此密钥从来没有产生一击,如果图像不在L1缓存它在线提取。当图像在线获取时,它会保存在磁盘缓存中,但Volley会以URL(仅URL)作为关键字来保存它。

这是预期的行为?我错过了什么吗?

+0

它可能取决于您的回应标题 – njzk2

+1

你知道为什么凌空不会产生热门吗? – iamrelos

+0

您可以使用[droidQuery](http://bit.ly/droidquery)来完成异步请求缓存(Ajax),并且控制缓存更容易(无论是否,以及保留缓存对象多长时间)。 – Phil

回答

-1

这是您希望它工作的确切方式。

  1. 点击网址,并获取图片时,它不可用。
  2. 从缓存中加载图像(如果可用)。
+0

这没有意义。首先,您要在点击url之前从缓存中加载图像。其次,这并不回答我的问题,关于如何排除工作 – Markus

+0

我理解你的问题,就像你在上面的评论中提到的方式一样。 –

+0

我不明白你在说什么。我问“为什么内部高速缓存永远不会产生命中” – Markus

1

你可以发布你的类实现ImageCache。

我刚才一直在寻找这个自己,并在我的代码中实现我没有将位图添加到内存缓存中,因此它每次都会从磁盘重新加载它。

这是我的意思一个简单的例子,我要去哪里错了

@Override 
    public Bitmap getBitmap(String cachKey) { 

     Bitmap b = null; 

      //check the memory first 
      b = memoryCache.get(cacheKey); 
      if(b == null){ 
       //memory cache was null, check file cache   
       b = diskLruImageCache.getBitmap(cacheKey); 

       // this is where it needs to be added to your memory cache 
       if(b != null){ 
        memoryCache.put(url, b); 
       } 
      } 



     return b; 
    } 
9

你没有得到任何匹配的原因是因为磁盘缓存在凌空的默认行为是依赖于HTTP您请求的元素的标题(在您的情况下,图像)。

排球的工作方式是:

  1. ImageLoader检查L1高速缓存(由您在其构造提供给ImageLoader内存缓存)。如果可用返回图像。
  2. 请求处理RequestQueue。它检查图像的L2(磁盘缓存)。
  3. 如果在磁盘缓存中找到,请检查映像到期时间。如果没有过期,则返回。
  4. 下载图像并返回。
  5. 将图像保存在缓存中。

如果你想在默认的设置工作,图像必须有一个Cache-Control头像max-age=???其中问号表示从其所下载的时间足够秒。

如果您想更改默认行为,我不确定,但我认为您必须编辑一些代码。

查看Volley资源中的CacheDispatcher类。

1

我今天在自己的应用中追踪了这个问题。我在构造函数中设置了以KB为单位的最大缓存大小,但是在sizeOf()中报告了以字节为单位的大小,因此没有任何缓存。

This answer给我挺身而出。

0

如果在响应头中没有设置缓存控制,则排气不会缓存任何东西。

检查HttpHeaderParser Volley中的类实现。

缓存可以基于最大年龄或电子标签。检查您的响应标题并确定设置的任何内容。它看起来像这样。

的Cache-Control→公众,最大年龄= 300

Cache Header info

1

也许你正在使用NetworkImageView加载图像。您可以使用ImageView和ImageLoader来做同样的事情。对于任何图像大小,使用ImageLoader时,密钥中的元数据就像“#W0#H0”。

ImageLoader imageLoader = getImageLoader(); 
imageLoader.get(url, ImageLoader.getImageListener(imageView, defaultDrawable, errorDrawable));