Android Volley ImageLoader-BitmapLruCache参数?

Android Volley ImageLoader-BitmapLruCache参数?,android,image-loading,bitmapcache,android-volley,Android,Image Loading,Bitmapcache,Android Volley,使用新的Volley库实现图像缓存时遇到问题。在演示文稿中,代码如下所示 mRequestQueue = Volley.newRequestQueue(context); mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache()); BitmapLruCache显然不包含在工具箱中。你知道如何实现它或者给我指一些资源吗 @14:38 谢谢 导入android.graphics.Bitmap; import androi

使用新的Volley库实现图像缓存时遇到问题。在演示文稿中,代码如下所示

mRequestQueue = Volley.newRequestQueue(context);
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());
BitmapLruCache显然不包含在工具箱中。你知道如何实现它或者给我指一些资源吗

@14:38

谢谢

导入android.graphics.Bitmap;
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);
    }
}
导入android.support.v4.util.LruCache; 公共类BitmapLruCache扩展LruCache实现ImageCache{ 公共静态int getDefaultLruCacheSize(){ final int maxMemory=(int)(Runtime.getRuntime().maxMemory()/1024); 最终int cacheSize=maxMemory/8; 返回缓存大小; } 公共BitmapLruCache(){ 这个(getDefaultLruCacheSize()); } 公共BitmapLruCache(int-sizeInKiloBytes){ 超级(sizeInKiloBytes); } @凌驾 受保护的int-sizeOf(字符串键、位图值){ 返回值.getRowBytes()*value.getHeight()/1024; } @凌驾 公共位图getBitmap(字符串url){ 返回get(url); } @凌驾 公共位图(字符串url、位图){ put(url、位图); } }
我的建议是使用单例位图缓存,以便在应用程序的整个生命周期内都可以使用该缓存

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);
    }
}
公共类BitmapCache实现ImageCache{
私人LruCache-mMemoryCache;
私有静态位图缓存分钟数;
专用位图缓存(上下文ctx){
final int memClass=((活动管理器)ctx
.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
//将可用内存的1/16用于此内存缓存。
最终int cacheSize=1024*1024*memClass/16;
mMemoryCache=新的LruCache(缓存大小){
@凌驾
受保护的int-sizeOf(字符串键、位图值){
返回值.getRowBytes()*value.getHeight();
}
};
}
公共静态BitmapCache getInstance(上下文ctx){
if(minInstance==null){
MinInstance=新的位图缓存(ctx);
}
回报率;
}
@凌驾
公共位图getBitmap(字符串url){
返回mMemoryCache.get(url);
}
@凌驾
公共位图(字符串url、位图){
mMemoryCache.put(url、位图);
}
}

Ficus为位图LRU提供了以下示例代码:


下面是一个使用基于磁盘的LRU缓存的示例。它基于使用Jake Wharton维护的AOSP DiskLruCache版本


编辑:我已经更新了项目,将内存中的LRU缓存作为默认实现,因为这是推荐的方法。Volley在其自己的二级缓存中隐式处理基于磁盘的缓存。图像缓存只是一级缓存。我更新了原始帖子,并在这里添加了更多细节:

这是一个新的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);
    }
}
公共类BitmapMemCache扩展LruCache实现ImageCache{
公共BitmapMemCache(){
这((int)(Runtime.getRuntime().maxMemory()/1024)/8);
}
公共BitmapMemCache(int-sizeInKiloBytes){
超级(sizeInKiloBytes);
}
@凌驾
受保护的int-sizeOf(字符串键、位图){
int size=bitmap.getByteCount()/1024;
返回大小;
}
公共布尔包含(字符串键){
return get(key)!=null;
}
公共位图getBitmap(字符串键){
位图位图=获取(键);
返回位图;
}
公共位图(字符串url、位图){
put(url、位图);
}
}

非常感谢,顺便问一下,如何确定缓存的正确大小?他说这是屏幕大小的函数,似乎是合乎逻辑的,但我该如何使它更精确?@Vlasto Benny Lava,我不确定,但像
N*screen\u width*screen\u height
N~10
这样的东西对我来说似乎是合乎逻辑的。因为现在发生的事情很好,但如果它离开屏幕回来,图像会再次加载,所以我猜它是从内存缓存中被踢出来的,对吗?知道那是什么吗?@Vlasto Benny Lava,缓存大小可能是个问题。现在如何计算?@njzk2可防止
int
溢出
Runtime.maxMemory()
返回
long
并强制转换为
int
会导致溢出。划分只是为了最小化这种可能性。在您的库中,您似乎在使用url.hashCode()生成磁盘缓存所需的密钥。那真的安全吗?哈希代码不是唯一的,所以对于随机解析为同一哈希代码的URL,您不会冒险获得错误的缓存命中吗?我见过其他人使用MD5来降低冲突风险,有些人甚至提供自己的MD5实现来避免Androids非线程安全MessageDigest类。关于这个(潜在的)问题有什么建议吗?你是对的,这只是为了演示而准备的,并且大部分时间都有效。我正在测试UUID.fromString()的速度,作为一种可行的替代方法。