使用缓存来存储位图

时间:2014-01-16 09:49:59

标签: android caching bitmap android-lru-cache

我正在使用LruCache来存储位图。

这是我运行以存储位图的异步任务。

new AsyncTask<Void, Void, Bitmap>() {

        @Override
        protected Bitmap doInBackground(Void... args) {
            String url = d.getImageUrl();
            if (url != null && !url.equals("")) {
                try {
                    LogUtils.log("getting image from cache");
                    Bitmap image = imageCache.getBitmapFromMemCache(url);
                    if (image == null) {

                        image = BitmapFactory.decodeStream(new URL(url)
                                .openConnection().getInputStream());
                        LogUtils.log("storing image to cache");
                        imageCache.addBitmapToMemoryCache(url, image);
                    } else {
                        LogUtils.log("got image from cache");
                    }
                    return image;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;

        }

        @Override
        protected void onPostExecute(Bitmap image) {
            if (holder.image != null) {
                if (image != null) {
                    holder.image.setImageBitmap(image);
                    holder.image.setVisibility(View.VISIBLE);
                }   
            }

        }

    }.execute();

这是我的缓存实现:

public class ImageCache {

private static ImageCache instance;

public static ImageCache getInstance(Context context) {
    if (instance == null)
        instance = new ImageCache(context);
    return instance;
}

private LruCache<String, Bitmap> mMemoryCache;

private ImageCache(Context context) {
    // Get memory class of this device, exceeding this amount will throw an
    // OutOfMemory exception.
    final int memClass = ((ActivityManager) context
            .getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();

    final int cacheSize = (1024 * 1024 * memClass)/8;


    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            // The cache size will be measured in bytes rather than number
            // of items.
            return bitmap.getRowBytes() * bitmap.getHeight();
        }
    };
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    LogUtils.log("key: " + key);
    if (getBitmapFromMemCache(key) == null) {
        mMemoryCache.put(key, bitmap);
    } 
}

public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
}

}

在我的清单中我也有:

android:largeheap="true"

问题在于我的ListView ...当我向下滚动时...图像从网址重新加载,代码到达这一行:

LogUtils.log("storing image to cache");

可能导致此问题的原因是什么?

1 个答案:

答案 0 :(得分:0)

感谢@Ascorbin,我找到了答案!无需重新发明轮子。 我用过这个库:

https://github.com/nostra13/Android-Universal-Image-Loader

如果有人遇到与我相同的问题...那就是......缓存的图片从网站重新加载......然后使用该库和此代码段设置图片:

        DisplayImageOptions options = new DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.noimage) // resource or drawable
        .showImageForEmptyUri(R.drawable.noimage) // resource or drawable
        .resetViewBeforeLoading(true)  
        .delayBeforeLoading(0)
        .cacheInMemory(true) 
        .cacheOnDisc(true) 
        .bitmapConfig(Bitmap.Config.ARGB_8888) 
        .build();


        String url = d.getImageUrl();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(v.getContext())
                .defaultDisplayImageOptions(options)
                .build();
        ImageLoader imageLoader = ImageLoader.getInstance();
        imageLoader.init(config);
        imageLoader.displayImage("", holder.image);
        imageLoader.displayImage(url, holder.image);