简体   繁体   English

Android凌空图像缓存问题

[英]Android volley image caching questions

in the google's own volley image cache tutorial 在谷歌自己的凌空图像缓存教程中

// 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;
}

the recommended cache is three screens worth of images which equals to 7mb. 推荐的缓存是三个屏幕的图像,相当于7mb。 I have an social media app and there is a newsfeed inside it. 我有一个社交媒体应用程序,里面有新闻源。

1-) My first question is what will happen after the cache is full? 1-)我的第一个问题是缓存满后会发生什么?

2-) I am thinking about removing cache every one hour and thus the cache will include the newer content. 2-)我正在考虑每隔一小时删除一次缓存,因此缓存将包含更新的内容。 Is that reasonable ? 这合理吗? What is the image caching logic behind the apps which includes something like newsfeed(for example, instagram)? 应用程序背后的图像缓存逻辑是什么,包括新闻源(例如,Instagram)?

3-) How can i remove the old cache of specific item and force it to download it again? 3-)如何删除特定项目的旧缓存并强制它再次下载? I tried this solution but it did not work: 我试过这个解决方案,但它不起作用:

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

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

There are a lots of clone question of my third question but none of them has been answered. 我的第三个问题有很多克隆问题,但没有一个问题得到解答。

Thanks for your helps. 谢谢你的帮助。 :) :)

1.) There are 2 layers of cache in Volley, one is the in-memory cache (in RAM) and the other one is a disk cache. 1.)Volley中有两层缓存,一个是内存缓存(在RAM中),另一个是磁盘缓存。 Once a cache is full, the oldest image (meaning the image that hasn't been accessed the longest) in that cache will be evicted when a new image is about to be cached to make room for the new items. 一旦缓存已满,当将要缓存新图像以为新项目腾出空间时,将清除该缓存中最旧的图像(意味着未访问最长的图像)。 When something is evicted from the in-memory cache, it is still present in the disk cache and can be loaded very quickly from disk if it is needed again. 当从内存缓存中清除某些内容时,它仍然存在于磁盘缓存中,并且如果再次需要,可以非常快速地从磁盘加载。 If an image is evicted from the disk cache, it would have to be redownloaded if it's needed again. 如果从磁盘缓存中清除映像,则必须重新加载它,如果需要再次加载。

2.) This doesn't sound reasonable once you understood the answer to question 1. The cache automatically makes room for newer content and there is no reason to evict content manually. 2.)一旦您理解了问题1的答案,这听起来就不合理。缓存会自动为更新的内容腾出空间,并且没有理由手动逐出内容。 Manual eviction will in fact lower your cache's efficiency. 实际上,手动驱逐会降低缓存的效率。

3.) Broadly speaking, this is not possible (without hacks), because it should not be needed. 3.)从广义上讲,这是不可能的(没有黑客攻击),因为它不应该被需要。 If an image resource (almost) always expires after a certain time, the server should announce this using HTTP headers when sending the resource to the client. 如果图像资源(几乎)总是在一定时间后过期,则服务器应在将资源发送到客户端时使用HTTP头声明。 For example using the max-age property of the cache-control header. 例如,使用缓存控制头的max-age属性。 There are lots of websites explaining this in detail, for example: http://www.mobify.com/blog/beginners-guide-to-http-cache-headers/ . 有很多网站详细解释了这一点,例如: http//www.mobify.com/blog/beginners-guide-to-http-cache-headers/ If an image resource almost never expires, you can consider changing its filename upon change and store that filename as a property. 如果图像资源几乎永不过期,您可以考虑在更改时更改其文件名并将该文件名存储为属性。 For example a user can have an avatar property containing the URL to the avatar. 例如,用户可以具有包含化身的URL的化身属性。 The avatar image can be cached indefinitely and you change the URL of the image if a new avatar gets uploaded. 可以无限期缓存头像图像,如果上传新头像,则更改图像的URL。

For you 3rd question, I suggest that you read the following Google's documentation: 对于第3个问题,我建议您阅读以下Google的文档:

Request an Image 申请图片

ImageRequest —a canned request for getting an image at a given URL and calling back with a decoded bitmap. ImageRequest - 一个罐装请求,用于获取给定URL的图像并使用解码的位图进行回调。 It also provides convenience features like specifying a size to resize to. 它还提供了便利功能,例如指定要调整大小的大小。 Its main benefit is that Volley's thread scheduling ensures that expensive image operations (decoding, resizing) automatically happen on a worker thread. 它的主要好处是Volley的线程调度确保在工作线程上自动发生昂贵的图像操作(解码,调整大小)。

So if you use a ImageRequest only, you can refer to my answer at the following question: 因此,如果您仅使用ImageRequest,可以在以下问题中参考我的回答:

Tell Volley not to use cached data but to initiate a new request? 告诉Volley不要使用缓存数据,而是发起新请求?

Also in the Google's documentation: 另外在Google的文档中:

ImageLoader —a helper class that handles loading and caching images from remote URLs. ImageLoader - 一个辅助类,用于处理从远程URL加载和缓存图像。 ImageLoader is a an orchestrator for large numbers of ImageRequests, for example when putting multiple thumbnails in a ListView. ImageLoader是大量ImageRequests的协调器,例如在ListView中放置多个缩略图时。 ImageLoader provides an in-memory cache to sit in front of the normal Volley cache ,... ImageLoader提供了一个内存缓存,可以放在普通的Volley缓存之前 ,......

If you use NetworkImageView, you can refer to my answer at the following question: 如果您使用NetworkImageView,可以在以下问题中参考我的回答:

Disable or Remove Cache in NetworkImageView- Volley 在NetworkImageView- Volley中禁用或删除缓存

In which you will find that I use the following code inside VolleySingleton class: 在其中你会发现我在VolleySingleton类中使用以下代码:

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

        @Override
        public void putBitmap(String url, Bitmap bitmap) {
        }
    });

Hope it helps! 希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM