Android Volley 图片加载器 - BitmapLruCache 参数是什么?

35

我在使用新的Volley库实现图像缓存时遇到了问题。在演示中,代码看起来是这样的:

mRequestQueue = Volley.newRequestQueue(context);
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());

BitmapLruCache显然不包含在工具包中。是否有任何实现它或指向一些资源的想法?

http://www.youtube.com/watch?v=yhv8l9F44qo @14:38

谢谢!

5个回答

50
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageCache {
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    public BitmapLruCache() {
        this(getDefaultLruCacheSize());
    }

    public BitmapLruCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

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

非常感谢,顺便问一下,您如何确定缓存的适当大小?他说这是屏幕大小的函数,听起来很合理,但我该如何使其更精确? - urSus
@Vlasto Benny Lava,我不确定,但是像 N * screen_width * screen_height 这样的公式,其中 N ~ 10 对我来说似乎很合理。 - Vladimir Mironov
@Vlasto,缓存大小可能会成为一个问题。现在它是如何计算的? - Vladimir Mironov
2
为了防止int溢出,建议使用@njzk2。Runtime.maxMemory()返回的是long类型,强制转换为int可能会导致溢出。这里的除法只是为了尽量减小可能性。 - Vladimir Mironov
请注意,如果您要支持小于API 12的设备,则应确保使用支持v4库版本的LruCache而不是标准版本,否则它将在Gingerbread设备上崩溃。 - DesignatedNerd
显示剩余4条评论

7

5
这是一个使用基于磁盘的LRU缓存与Volley的示例。它基于Jake Wharton维护的AOSP DiskLruCache的版本。http://blogs.captechconsulting.com/blog/raymond-robinson/google-io-2013-volley-image-cache-tutorial 编辑:我已更新项目,将内存LRU缓存作为默认实现,因为这是推荐的方法。Volley隐式处理其自己的L2缓存中的基于磁盘的缓存。图像缓存只是L1缓存。我更新了原始帖子,并在此处添加了一些更多的细节:http://www.thekeyconsultant.com/2013/06/update-volley-image-cache.html

1
在你的库中,你似乎使用url.hashCode()来生成磁盘缓存所需的键。这样真的安全吗?hashCode不是唯一的,所以你不会冒险因为URL随机解析到相同的哈希码而得到错误的缓存命中吗?我看到其他人使用MD5来减少碰撞的风险,甚至提供自己的MD5实现来避免Android的非线程安全MessageDigest类。对于这个(潜在的)问题有什么建议吗? - Nicolai Buch-Andersen
1
你说得对,这只是为了演示而设置的,大部分时间都有效。我正在测试UUID.fromString()作为可行替代方案的速度。 - rdrobinson3

1

我的建议是使用单例位图缓存,这样缓存将在应用程序的整个生命周期内可用。

public class BitmapCache implements ImageCache {
    private LruCache<String, Bitmap> mMemoryCache;

    private static BitmapCache mInstance;

    private BitmapCache(Context ctx) {
        final int memClass = ((ActivityManager) ctx
                .getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
        // Use 1/16th of the available memory for this memory cache.
        final int cacheSize = 1024 * 1024 * memClass / 16;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }
        };
    }

    public static BitmapCache getInstance(Context ctx) {
        if (mInstance == null) {
            mInstance = new BitmapCache(ctx);
        }
        return mInstance;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return mMemoryCache.get(url);
    }

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

0

这是新的API,用于处理OOM。

public class BitmapMemCache extends LruCache<string, Bitmap> implements ImageCache {

    public BitmapMemCache() {
        this((int) (Runtime.getRuntime().maxMemory() / 1024) / 8);
    }

    public BitmapMemCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap bitmap) {
        int size = bitmap.getByteCount() / 1024;
        return size;
    }

    public boolean contains(String key) {
        return get(key) != null;
    }

    public Bitmap getBitmap(String key) {
        Bitmap bitmap = get(key);
        return bitmap;
    }

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接