【问题标题】:Android volley image caching questionsAndroid volley 图片缓存问题
【发布时间】:2016-04-16 13:21:43
【问题描述】:

在google自己的volley图片缓存教程中

// Returns a cache size equal to approximately three screens worth of images.
public static int getCacheSize(Context ctx) {
    final DisplayMetrics displayMetrics = ctx.getResources().
            getDisplayMetrics();
    final int screenWidth = displayMetrics.widthPixels;
    final int screenHeight = displayMetrics.heightPixels;
    // 4 bytes per pixel
    final int screenBytes = screenWidth * screenHeight * 4;

    return screenBytes * 3;
}

推荐的缓存是三个屏幕的图像,等于 7mb。我有一个社交媒体应用,里面有一个新闻源。

1-) 我的第一个问题是缓存满后会发生什么?

2-) 我正在考虑每隔一小时删除一次缓存,因此缓存将包含较新的内容。这合理吗?应用程序背后的图像缓存逻辑是什么,包括新闻源(例如,instagram)?

3-) 如何删除特定项目的旧缓存并强制它重新下载?我尝试了这个解决方案,但没有奏效:

VolleySingleton.getInstance().getRequestQueue().getCache().remove(IMAGE_URL);

mNetworkImageView = (NetworkImageView) getView().findViewById(R.id.networkImageView);
mImageLoader = VolleySingleton.getInstance().getImageLoader();
mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);

我的第三个问题有很多克隆问题,但没有一个得到回答。

感谢您的帮助。 :)

【问题讨论】:

    标签: java android image caching android-volley


    【解决方案1】:

    1.) Volley 中有两层缓存,一层是内存缓存(在 RAM 中),另一层是磁盘缓存。一旦缓存已满,当即将缓存新图像以为新项目腾出空间时,该缓存中最旧的图像(即未访问时间最长的图像)将被逐出。当从内存缓存中清除某些内容时,它仍然存在于磁盘缓存中,并且如果再次需要它可以非常快速地从磁盘加载。如果图像从磁盘缓存中被逐出,如果再次需要它就必须重新下载。

    2.) 一旦您理解了问题 1 的答案,这听起来并不合理。缓存会自动为较新的内容腾出空间,没有理由手动驱逐内容。手动驱逐实际上会降低缓存的效率。

    3.) 从广义上讲,这是不可能的(没有 hack),因为它不应该是必需的。如果图像资源(几乎)总是在一定时间后过期,则服务器应在将资源发送到客户端时使用 HTTP 标头宣布这一点。例如使用缓存控制标头的 max-age 属性。有很多网站对此进行了详细解释,例如:http://www.mobify.com/blog/beginners-guide-to-http-cache-headers/。如果图像资源几乎永不过期,您可以考虑在更改时更改其文件名并将该文件名存储为属性。例如,用户可以拥有一个包含头像的 URL 的头像属性。头像图片可以无限期缓存,如果上传了新头像,您可以更改图片的 URL。

    【讨论】:

    • 嘿 Fabian,非常感谢您的完美回答,现在我明白了我该怎么做。我可以再问一个问题吗?我如何确定项目的最佳缓存大小,就像我在第一篇文章中提到的那样?此外,还有两种类型的图像,一种是原始的,另一种是预览的。我应该将它们都添加到数据库中还是添加唯一的原始数据库并通过在应用程序中为我的所有列表视图手动减小宽度和高度来创建预览?非常感谢。
    【解决方案2】:

    对于您的第三个问题,我建议您阅读以下 Google 文档:

    Request an Image

    ImageRequest——在给定 URL 处获取图像的预设请求和 用解码的位图回调。也提供了便利 诸如指定要调整大小的大小之类的功能。它的主要好处是 Volley 的线程调度确保了昂贵的图像操作 (解码、调整大小)自动发生在工作线程上。

    所以如果你只使用 ImageRequest,你可以参考我对以下问题的回答:

    Tell Volley not to use cached data but to initiate a new request?

    也在 Google 的文档中:

    ImageLoader——处理加载和缓存图像的辅助类 从远程 URL。 ImageLoader 是一个大数据的编排器 ImageRequests,例如将多个缩略图放在一个 列表显示。 ImageLoader 提供一个内存缓存来放置在前面 普通的 Volley 缓存,...

    如果你使用NetworkImageView,可以参考我对以下问题的回答:

    Disable or Remove Cache in NetworkImageView- Volley

    您会发现我在 VolleySingleton 类中使用了以下代码:

        mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
            @Override
            public Bitmap getBitmap(String url) {
                return null;
            }
    
            @Override
            public void putBitmap(String url, Bitmap bitmap) {
            }
        });
    

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 2013-05-22
      • 1970-01-01
      • 1970-01-01
      • 2013-10-24
      • 2014-03-17
      相关资源
      最近更新 更多