安卓:图像缓存stategy和内存缓存大小缓存、图像、大小、内存

2023-09-05 09:07:51 作者:深爱不腻゜

我实现图像缓存系统缓存下载的图像。

I'm implementing an image cache system for caching downloaded image.

我的策略是基于二级缓存: 存储器级和磁盘级

My strategy is based upon two-level cache: Memory-level and disk-level.

我类非常相似的droidfu项目

我下载的图像被放入一个HashMap和位图OBJET是 包装一个SoftRererence对象中。也是每一个图像保存 永久磁盘。 如果所请求的图像被发现,但进 的Hashmap<字符串,SoftReference<位图>> 将要搜索的磁盘上, readed,然后推回散列映射。否则图像将 从网络上下载。 因为我存储图像到物理​​性装置momery,我已经加入了$ P $的支票pserve设备空间,并保持在一个1M的占用空间:

My downloaded images are put into an hashmap and the Bitmap objet is wrapped inside a SoftRererence object. Also every image is saved permanently to the disk. If a requested image is not found into the Hashmap<String,SoftReference<Bitmap>> it will be searched on the disk, readed, and then pushed back into the hashmap. Otherwise the image will be downloaded from the network. Since I store the images into the phisical device momery, I have added a check for preserve the device space and stay under a 1M of occupied space:

private void checkCacheUsage() {

        long size = 0;
        final File[] fileList = new File(mCacheDirPath).listFiles();
        Arrays.sort(fileList, new Comparator<File>() {
            public int compare(File f1, File f2) {
                return Long.valueOf(f2.lastModified()).compareTo(
                        f1.lastModified());
            }
        });
        for (File file : fileList) {
            size += file.length();
            if (size > MAX_DISK_CACHE_SIZE) {
                file.delete();
                Log.d(ImageCache.class.getSimpleName(),
                        "checkCacheUsage: Size exceeded  " + size + "("
                                + MAX_DISK_CACHE_SIZE + ") wiping older file {"+file.toString()+"}");
            }
        }

    }

此方法有时称为AFTE磁盘写:

This method is called sometime afte a disk writing:

Random r = new Random();
        int ra = r.nextInt(10);

        if (ra % 2 == 0){
            checkCacheUsage();
        }

我想补充的是在HashMap的大小,以prevent它会成长太多相同的检查。事情是这样的:

What I'd like to add is the same check on the HashMap size to prevent it will grow too much. Something like this:

private synchronized void checkMemoryCacheUsage(){

            long size = 0;

            for (SoftReference<Bitmap> a : cache.values()) {

                final Bitmap b = a.get();

                if (b != null && ! b.isRecycled()){
                    size += b.getRowBytes() * b.getHeight();
                }

                if (size > MAX_MEMORY_SIZE){
                  //Remove some elements from the cache
                }

            }

            Log.d(ImageCache.class.getSimpleName(),
                    "checkMemoryCacheUsage: " + size + " in memory");

    }

我的问题是: 什么可能是一个正确的MAX_MEMORY_SIZE价值? 此外,这是一个好的方法吗? 一个很好的答案也可能是:不要做SoftReference已经足够了

My question is: What could be a right MAX_MEMORY_SIZE value? Also, Is it a good approach? A good answer also could be: "Don't do it! SoftReference is already enough"

推荐答案

不要这么做! SoftReference已经足够了! 实际上SoftReference是专门做正是你需要的。 有时SoftReference不会做你的需要。然后,你刚刚摆脱SoftReference,并编写您自己的内存管理逻辑。但据您使用SoftReference,你不应该担心内存消耗,SoftReference会为你。

Don't do it! SoftReference is already enough! Actually SoftReference is designed to do exactly what you need. Sometimes SoftReference doesn't do what you need. Then you just get rid of SoftReference and write your own memory management logic. But as far as you use SoftReference you should not be worried about memory consumption, SoftReference does it for you.