Android Volley ImageLoader - BitmapLruCache参数?
我在使用新的Volley库实现图像缓存时遇到了麻烦。在演示文稿中,代码如下所示Android Volley ImageLoader - BitmapLruCache参数?
mRequestQueue = Volley.newRequestQueue(context);
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());
BitmapLruCache显然不包含在工具包中。任何想法如何实现它或指向我的一些资源?
http://www.youtube.com/watch?v=yhv8l9F44qo @ 14:38个
谢谢!
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);
}
}
我建议使用Singleton位图缓存,这样这个缓存将在您的应用程序的整个生命周期中可用。
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);
}
}
这里是使用基于LRU缓存,排球磁盘的一个实例。它基于使用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。
在你的库中,你似乎在使用url.hashCode()来生成磁盘缓存所需的密钥。这真的很安全吗? hashCodes不是唯一的,所以你不会冒险得到URL的虚假缓存命中,它会随机解析为相同的哈希码?我见过其他人使用MD5来降低碰撞风险,有些甚至提供他们自己的MD5实现来避免Android非线程安全的MessageDigest类。有关这个(潜在)问题的任何建议? –
你是对的,这只是适合演示,并在大多数时间工作。我正在测试UUID.fromString()的速度作为一种可行的选择。 – rdrobinson3
这是进来新的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);
}
}
非常感谢,顺便说一句,你如何确定缓存的大小合适?他谈到它的屏幕尺寸功能似乎合乎逻辑,但我怎样才能使它更精确? – urSus
@Vlasto Benny Lava,我不确定,但是像'N * screen_width * screen_height'和'N〜10'这样的东西对我来说似乎是合乎逻辑的。 –
,因为现在发生的事很好,但是如果图像离开屏幕并返回,图像再次加载,所以我认为它被踢出了内存缓存?任何想法可能是什么? – urSus