结合使用LRU图像缓存和HTTPResponseCache进行磁盘和内存缓存 [英] Use LRU Image Caching In Conjuction With HTTPResponseCache for Disk and Memory Caching

查看:150
本文介绍了结合使用LRU图像缓存和HTTPResponseCache进行磁盘和内存缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最初的目标是同时使用磁盘和内存缓存.这将需要实现LRU缓存和DiskLruCache.但是,由于HTTPResponse缓存使用磁盘空间,因此我选择使用LRU缓存并执行con.setUseCaches(true);

Initially the objective was to use both disk and memory cache. This would require implementing LRU cache and DiskLruCache. However, since HTTPResponse cache uses disk space, I chose to use LRU cache and do con.setUseCaches(true);

问题是我不太了解首先要实现的内容. 对于LRU和DiskLru缓存,这是算法:

The problem is that I don't really understand what gets implemented first. For LRU and DiskLru cache, this is the algorithm:

首先检查图像的内存缓存

first check memory cache for an image

如果有图片,请将其返回并更新缓存

if there is an image, return it and update caches

其他检查磁盘缓存

如果磁盘缓存中有映像,则将其返回并更新缓存

if disk cache has an image, return it and update caches

其他从互联网下载图像,返回并更新缓存

else download image from the internet, return it and update caches

现在输入以下代码:

public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    private int inSampleSize = 0;

    private String imageUrl;

    private BaseAdapter adapter;

    private ImagesCache cache;

    private int desiredWidth, desiredHeight;

    private Bitmap image = null;

    private ImageView ivImageView;

    Context mContext;

    public DownloadImageTask(BaseAdapter adapter, int desiredWidth, int desiredHeight) {
        this.adapter = adapter;

        this.cache = ImagesCache.getInstance();

        this.desiredWidth = desiredWidth;

        this.desiredHeight = desiredHeight;
    }

    public DownloadImageTask(Context mContext, ImagesCache cache, ImageView ivImageView, int desireWidth, int desireHeight) {
        this.cache = cache;

        this.ivImageView = ivImageView;

        this.desiredHeight = desireHeight;

        this.desiredWidth = desireWidth;

        this.mContext = mContext;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        imageUrl = params[0];

        return getImage(imageUrl);
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        if (result != null) {
            cache.addImageToWarehouse(imageUrl, result);
            if (ivImageView != null) {
                ivImageView.setImageBitmap(result);
            }
            else {
            }
            if (adapter != null) {
                adapter.notifyDataSetChanged();
            }
        }
                /*
        * IMPORTANT:
        * This enables your retrieval from the cache when working offline
        */
        /***
         * Force buffered operations to the filesystem. This ensures that responses
         * written to the cache will be available the next time the cache is opened,
         * even if this process is killed.
         */
        HttpResponseCache cache = HttpResponseCache.getInstalled();
        if(cache != null) {
            //the number of HTTP requests issued since this cache was created.
            Log.e("total num HTTP requests", String.valueOf(cache.getHitCount()));
            //the number of those requests that required network use.
            Log.e("num req network", String.valueOf(cache.getNetworkCount()));
            //the number of those requests whose responses were served by the cache.
            Log.e("num use cache", String.valueOf(cache.getHitCount()));
            //   If cache is present, flush it to the filesystem.
            //   Will be used when activity starts again.
            cache.flush();
            /***
             * Uninstalls the cache and releases any active resources. Stored contents
             * will remain on the filesystem.
             */
            //UNCOMMENTING THIS PRODUCES A java.lang.IllegalStateException: cache is closedtry {
              //  cache.close();
            //}
            //catch(IOException e){
              //  e.printStackTrace();
            //}
        }
    }

    private Bitmap getImage(String imageUrl) {
        if (cache.getImageFromWarehouse(imageUrl) == null) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            options.inSampleSize = inSampleSize;
            //installing the cache at application startup.
            try {
                HttpResponseCache cache = HttpResponseCache.getInstalled();
                if (cache == null) {
                    File httpCacheDir = new File(mContext.getCacheDir(), "http");
                    long HTTP_CACHE_SIZE_IN_BYTES = 1024 * 1024 * 1024; // 1GB
                    HttpResponseCache.install(httpCacheDir, HTTP_CACHE_SIZE_IN_BYTES);
                    //Log.e("Max DiskLRUCache Size", String.valueOf(DiskLruCache.getMaxSize());
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            try {
                int readTimeout = 300000;
                int connectTimeout = 300000;
                URL url = new URL(imageUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setUseCaches(true);
                connection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);
                connection.setConnectTimeout(connectTimeout);
                connection.setReadTimeout(readTimeout);
                InputStream stream = connection.getInputStream();
                image = BitmapFactory.decodeStream(stream, null, options);
                int imageWidth = options.outWidth;
                int imageHeight = options.outHeight;
                if (imageWidth > desiredWidth || imageHeight > desiredHeight) {
                    System.out.println("imageWidth:" + imageWidth + ", imageHeight:" + imageHeight);
                    inSampleSize = inSampleSize + 2;
                    getImage(imageUrl);
                }
                else {
                    options.inJustDecodeBounds = false;
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setUseCaches(true);
                    connection.addRequestProperty("Cache-Control", "only-if-cached");
                    connection.setConnectTimeout(connectTimeout);
                    connection.setReadTimeout(readTimeout);
                    stream = connection.getInputStream();
                    image = BitmapFactory.decodeStream(stream, null, options);
                    return image;
                }
            }
            catch (Exception e) {
                Log.e("getImage", e.toString());
            }
        }
        return image;
    }
}

它好像在doInBackground()中保存到HttpResponseCache,在onPostExecute()中保存相同的图像到LRUCache.我想做的是:

It appears as though in doInBackground() I am saving to HttpResponseCache and in onPostExecute() I am saving the same image to LRUCache. What I would like to do is:

如果未缓存图像,则将其保存到HttpResponseCache 如果HttpResponseCache已满,请保存到LRUCache. 如果两者都已满,请使用默认的删除机制删除旧的未使用映像. 问题是同时保存到两个缓存中

If the image is not cached, save it to HttpResponseCache If HttpResponseCache is full, save to LRUCache. If both are full, use the default delete mechanisms to remove old unused images. The problem is saving to both caches and not either

**

**

推荐答案

如果有人想重用以上任何代码,我将只使用http响应缓存,而不使用LRU缓存,因为尤其是在缓存的情况下网络服务响应,例如JSON,xml.为什么?

If anyone wants to re-use any of the above code, I would take only the http response cache and not use the LRU cache since especially if you are caching webservice response e.g. JSON,xml. Why?

由于上述LRU缓存的实现,我曾经丢失了200MB的设备存储空间.

I once lost 200MB of device storage due to the LRU cache implementation above.

HTTPResponseCache的优点:

Advantages of HTTPResponseCache:

  • 将HTTP和HTTPS响应缓存到文件系统,以便它们可以 重复使用,节省时间和带宽
  • HttpUrlConnection可以:自动处理缓存机制,
  • 借助以下功能加快应用程序的响应时间 HttpResponseCache
  • 从API级别1 =>开始可用,它经受了时间的考验,并且功能强大
  • Caches HTTP and HTTPS responses to the filesystem so they may be reused, saving time and bandwidth
  • HttpUrlConnection does: Automatic handling of the caching mechanisms,
  • Speeds up response time of the application with the help of HttpResponseCache
  • It has been available since API level 1=> it has stood the test of time and is robust

另一方面:

尽管LRUCache优于DiskLRUCache:

While LRUCache has its advantages over DiskLRUCache:

  • 您必须实现该类(和其他帮助程序类),这意味着如果android开发人员上的代码发生更改,则在不赞成使用以前的实现之后,您的应用程序中断后,您将必须不断下载和编辑本地版本./li>
  • 删除映像后,您可能仍会发现磁盘空间正在使用,因为映像将位于设备中的某个位置(就像我的情况一样).
  • You have to implement the class (and other helper classes), meaning if the code on android developers changes, you will have to constantly download and edit your local version after your app breaks after the previous implementation would have been deprecated.
  • After removing the image, you might still find your disk space being used as the image will be somewhere in your device (as with my case).

那是结论...

这篇关于结合使用LRU图像缓存和HTTPResponseCache进行磁盘和内存缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆