【问题标题】:Android Volley ImageLoader - BitmapLruCache parameter?Android Volley ImageLoader - BitmapLruCache 参数?
【发布时间】:2013-05-22 02:37:11
【问题描述】:

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

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

BitmapLruCache 显然不包含在工具包中。知道如何实现它或向我指出一些资源吗?

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

谢谢!

【问题讨论】:

    标签: android image-loading bitmapcache android-volley


    【解决方案1】:
    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);
        }
    }
    

    【讨论】:

    • 非常感谢,顺便问一下,您如何确定合适的缓存大小?他谈到它是屏幕尺寸的函数,似乎合乎逻辑,但我如何让它更准确?
    • @Vlasto Benny Lava,我不确定,但像 N * screen_width * screen_heightN ~ 10 这样的东西对我来说似乎是合乎逻辑的。
    • 因为现在发生的事情很好,但是如果图像离开屏幕并返回,它会再次加载,所以我认为它被踢出内存缓存对吗?知道那可能是什么吗?
    • @Vlasto Benny Lava,缓存大小可能是个问题。现在是怎么计算的?
    • @njzk2 防止int 溢出。 Runtime.maxMemory() 返回 long 并强制转换为 int 会导致溢出。划分只是为了尽量减少可能性。
    【解决方案2】:

    Ficus 为 Bitmap LRU 提供了这个示例代码:

    https://gist.github.com/ficusk/5614325

    【讨论】:

      【解决方案3】:

      这是一个使用 Volley 的基于磁盘的 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() 的速度作为一种可行的替代方案。
      【解决方案4】:

      我的建议是使用单例位图缓存,以便在您的应用程序的整个生命周期中都可以使用此缓存。

      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);
          }
      }
      

      【讨论】:

        【解决方案5】:

        这是处理 OOM 的新 API

        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);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2013-08-20
          • 2015-09-30
          • 2013-08-03
          • 1970-01-01
          • 1970-01-01
          • 2016-08-12
          • 2014-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多