前言:

上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小。我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发生的概率呢?之前我们一直在使用SoftReference软引用,SoftReference是一种现在已经不再推荐使用的方式,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用变得不再可靠,所以今天我们来认识一种新的缓存处理算法Lru,然后学习一下基于Lru的Lrucache、DiskLruCache 实现我们的图片缓存。

Lru:

LRU是Least Recently Used 的缩写,翻译过来就是“最近最少使用”,LRU缓存就是使用这种原理实现,简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉,比如我们缓存10000条数据,当数据小于10000时可以随意添加,当超过10000时就需要把新的数据添加进来,同时要把过期数据删除,以确保我们最大缓存10000条,那怎么确定删除哪条过期数据呢,采用LRU算法实现的话就是将最老的数据删掉。

基于LruCache实现内存缓存:

1.)初始化MemoryCache

这里内存缓存的是Drawable 而不是Bitmap 理由是Drawable相对Bitmap来说有很大的内存优势

 
  1. int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取系统分配给应用的总内存大小
  2. int mCacheSize = maxMemory / 8;//设置图片内存缓存占用八分之一
  3. mMemoryCache = new LruCache<String, Drawable>(mCacheSize) {
  4. //必须重写此方法,来测量Bitmap的大小
  5. @Override
  6. protected int sizeOf(String key, Drawable value) {
  7. if (value instanceof BitmapDrawable) {
  8. Bitmap bitmap = ((BitmapDrawable) value).getBitmap();
  9. return bitmap == null ? 0 : bitmap.getByteCount();
  10. }
  11. return super.sizeOf(key, value);
  12. }
  13. };
 

2.)添加一个Drawable到内存缓存

 
  1. /**
  2. * 添加Drawable到内存缓存
  3. *
  4. * @param key
  5. * @param drawable
  6. */
  7. private void addDrawableToMemoryCache(String key, Drawable drawable) {
  8. if (getDrawableFromMemCache(key) == null && drawable != null) {
  9. mMemoryCache.put(key, drawable);
  10. }
  11. }
 

3.)从内存缓存中获取一个Drawable

 
  1. /**
  2. * 从内存缓存中获取一个Drawable
  3. *
  4. * @param key
  5. * @return
  6. */
  7. public Drawable getDrawableFromMemCache(String key) {
  8. return mMemoryCache.get(key);
  9. }
 

4.)从内存缓存中移除一个Drawable

 
  1. /**
  2. * 从内存缓存中移除
  3. *
  4. * @param key
  5. */
  6. public void removeCacheFromMemory(String key) {
  7. mMemoryCache.remove(key);
  8. }
 

5.)清空内存缓存

  1. /**
  2. * 清理内存缓存
  3. */
  4. public void cleanMemoryCCache() {
  5. mMemoryCache.evictAll();
  6. }

其实Lru缓存机制本质上就是存储在一个LinkedHashMap存储,为了保障插入的数据顺序,方便清理。

基于DiskLruCache实现磁盘缓存:

DiskLruCache类并不是谷歌官方实现,需要自行下载,下载地址:https://github.com/JakeWharton/DiskLruCache

1.)初始化DiskLruCache

 
  1. File cacheDir = context.getCacheDir();//指定的是数据的缓存地址
  2. long diskCacheSize = 1024 * 1024 * 30;//最多可以缓存多少字节的数据
  3. int appVersion = DiskLruUtils.getAppVersion(context);//指定当前应用程序的版本号
  4. int valueCount = 1;//指定同一个key可以对应多少个缓存文件
  5. try {
  6. mDiskCache = DiskLruCache.open(cacheDir, appVersion, valueCount, diskCacheSize);
  7. } catch (Exception ex) {
  8. }
 

2.)写入一个文件到磁盘缓存

 
  1. /**
  2. * 添加Bitmap到磁盘缓存
  3. *
  4. * @param key
  5. * @param value
  6. */
  7. private void addBitmapToDiskCache(String key, byte[] value) {
  8. OutputStream out = null;
  9. try {
  10. DiskLruCache.Editor editor = mDiskCache.edit(key);
  11. if (editor != null) {
  12. out = editor.newOutputStream(0);
  13. if (value != null && value.length > 0) {
  14. out.write(value);
  15. out.flush();
  16. editor.commit();
  17. } else {
  18. editor.abort();
  19. }
  20. }
  21. mDiskCache.flush();
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. } finally {
  25. DiskLruUtils.closeQuietly(out);
  26. }
  27. }

3.)从磁盘缓存中读取Drawable

 
  1. /**
  2. * 从磁盘缓存中获取一个Drawable
  3. *
  4. * @param key
  5. * @return
  6. */
  7. public Drawable getDrawableFromDiskCache(String key) {
  8. try {
  9. DiskLruCache.Snapshot snapShot = mDiskCache.get(key);
  10. if (snapShot != null) {
  11. InputStream is = snapShot.getInputStream(0);
  12. Bitmap bitmap = BitmapFactory.decodeStream(is);
  13. Drawable drawable = DiskLruUtils.bitmap2Drawable(bitmap);
  14. //从磁盘中读取到之后 加入内存缓存
  15. addDrawableToMemoryCache(key, drawable);
  16. return drawable;
  17. }
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. return null;
  22. }
 

4.)从磁盘缓存中移除

 
  1. /**
  2. * 从磁盘缓存中移除
  3. *
  4. * @param key
  5. */
  6. public void removeCacheFromDisk(String key) {
  7. try {
  8. mDiskCache.remove(key);
  9. } catch (Exception e) {
  10. }
  11. }
 

5.)清空磁盘缓存

 
  1. /**
  2. * 清理磁盘缓存
  3. */
  4. public void cleanDiskCache() {
  5. try {
  6. mDiskCache.delete();
  7. } catch (Exception e) {
  8. }
  9. }
 

图片下载过程:

接下来实例中用到了一点RxJava的知识有不了解RxJava的请自行了解一下。

1.)采用异步方式操作磁盘缓存和网络下载, 内存缓存可以在主线程中操作

 
  1. public void disPlay(final ImageView imageView, String imageUrl) {
  2. //生成唯一key
  3. final String key = DiskLruUtils.hashKeyForDisk(imageUrl);
  4. //先从内存中读取
  5. Drawable drawableFromMemCache = getDrawableFromMemCache(key);
  6. if (drawableFromMemCache != null) {
  7. imageView.setImageDrawable(drawableFromMemCache);
  8. return;
  9. }
  10. Observable.just(imageUrl)
  11. .map(new Func1<String, Drawable>() {
  12. @Override
  13. public Drawable call(String imageUrl) { // 参数类型 String
  14. //从磁盘中读取
  15. Drawable drawableFromDiskCache = getDrawableFromDiskCache(key);
  16. if (drawableFromDiskCache != null) {
  17. return drawableFromDiskCache;
  18. }
  19. //网络下载
  20. return download(imageUrl); // 返回类型 Drawable
  21. }
  22. })
  23. .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
  24. .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
  25. .subscribe(new Action1<Drawable>() {
  26. @Override
  27. public void call(Drawable drawable) { // 参数类型 Drawable
  28. imageView.setImageDrawable(drawable);
  29. }
  30. });
  31. }
 

2.)下载图片过程以及处理

 
  1. private Drawable download(String imageUrl) {
  2. HttpURLConnection urlConnection = null;
  3. ByteArrayOutputStream bos = null;
  4. InputStream ins = null;
  5. try {
  6. final URL url = new URL(imageUrl);
  7. urlConnection = (HttpURLConnection) url.openConnection();
  8. ins = urlConnection.getInputStream();
  9. bos = new ByteArrayOutputStream();
  10. int b;
  11. while ((b = ins.read()) != -1) {
  12. bos.write(b);
  13. }
  14. bos.flush();
  15. byte[] bytes = bos.toByteArray();
  16. Bitmap bitmap = DiskLruUtils.bytes2Bitmap(bytes);
  17. String key = DiskLruUtils.hashKeyForDisk(imageUrl);
  18. Drawable drawable = DiskLruUtils.bitmap2Drawable(bitmap);
  19. //加入内存缓存
  20. addDrawableToMemoryCache(key, drawable);
  21. //加入磁盘缓存
  22. addBitmapToDiskCache(key, bytes);
  23. return drawable;
  24. } catch (IOException e) {
  25. e.printStackTrace();
  26. } finally {
  27. if (urlConnection != null) {
  28. urlConnection.disconnect();
  29. }
  30. DiskLruUtils.closeQuietly(bos);
  31. DiskLruUtils.closeQuietly(ins);
  32. }
  33. return null;
  34. }
 

附上最终图片缓存单例简单实现全部代码以及DiskLruUtils工具类代码

  1. ImageLoadManager.java
public class ImageLoadManager {
    private LruCache<String, Drawable> mMemoryCache;//内存缓存
    private DiskLruCache mDiskCache;//磁盘缓存
    private static ImageLoadManager mInstance;//获取图片下载单例引用

/**
     * 构造器
     *
     * @param context
     */
    private ImageLoadManager(Context context) {
        int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取系统分配给应用的总内存大小
        int mCacheSize = maxMemory / 8;//设置图片内存缓存占用八分之一
        mMemoryCache = new LruCache<String, Drawable>(mCacheSize) {
            //必须重写此方法,来测量Bitmap的大小
            @Override
            protected int sizeOf(String key, Drawable value) {
                if (value instanceof BitmapDrawable) {
                    Bitmap bitmap = ((BitmapDrawable) value).getBitmap();
                    return bitmap == null ? 0 : bitmap.getByteCount();
                }
                return super.sizeOf(key, value);
            }
        };

File cacheDir = context.getCacheDir();//指定的是数据的缓存地址
        long diskCacheSize = 1024 * 1024 * 30;//最多可以缓存多少字节的数据
        int appVersion = DiskLruUtils.getAppVersion(context);//指定当前应用程序的版本号
        int valueCount = 1;//指定同一个key可以对应多少个缓存文件
        try {
            mDiskCache = DiskLruCache.open(cacheDir, appVersion, valueCount, diskCacheSize);
        } catch (Exception ex) {
        }
    }

/**
     * 获取单例引用
     *
     * @return
     */
    public static ImageLoadManager getInstance(Context context) {
        ImageLoadManager inst = mInstance;
        if (inst == null) {
            synchronized (RequestManager.class) {
                inst = mInstance;
                if (inst == null) {
                    inst = new ImageLoadManager(context.getApplicationContext());
                    mInstance = inst;
                }
            }
        }
        return inst;
    }

public void disPlay(final ImageView imageView, String imageUrl) {
        //生成唯一key
        final String key = DiskLruUtils.hashKeyForDisk(imageUrl);
        //先从内存中读取
        Drawable drawableFromMemCache = getDrawableFromMemCache(key);
        if (drawableFromMemCache != null) {
            imageView.setImageDrawable(drawableFromMemCache);
            return;
        }
        Observable.just(imageUrl)
                .map(new Func1<String, Drawable>() {
                    @Override
                    public Drawable call(String imageUrl) { // 参数类型 String
                        //从磁盘中读取
                        Drawable drawableFromDiskCache = getDrawableFromDiskCache(key);
                        if (drawableFromDiskCache != null) {
                            return drawableFromDiskCache;
                        }
                        //网络下载
                        return download(imageUrl); // 返回类型 Drawable
                    }
                })
                .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
                .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
                .subscribe(new Action1<Drawable>() {
                    @Override
                    public void call(Drawable drawable) { // 参数类型 Drawable
                        imageView.setImageDrawable(drawable);
                    }
                });
    }

/**
     * 添加Drawable到内存缓存
     *
     * @param key
     * @param drawable
     */
    private void addDrawableToMemoryCache(String key, Drawable drawable) {
        if (getDrawableFromMemCache(key) == null && drawable != null) {
            mMemoryCache.put(key, drawable);
        }
    }

/**
     * 从内存缓存中获取一个Drawable
     *
     * @param key
     * @return
     */
    public Drawable getDrawableFromMemCache(String key) {
        return mMemoryCache.get(key);
    }

/**
     * 从磁盘缓存中获取一个Drawable
     *
     * @param key
     * @return
     */
    public Drawable getDrawableFromDiskCache(String key) {
        try {
            DiskLruCache.Snapshot snapShot = mDiskCache.get(key);
            if (snapShot != null) {
                InputStream is = snapShot.getInputStream(0);
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                Drawable drawable = DiskLruUtils.bitmap2Drawable(bitmap);
                //从磁盘中读取到之后 加入内存缓存
                addDrawableToMemoryCache(key, drawable);
                return drawable;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

/**
     * 添加Bitmap到磁盘缓存
     *
     * @param key
     * @param value
     */
    private void addBitmapToDiskCache(String key, byte[] value) {
        OutputStream out = null;
        try {
            DiskLruCache.Editor editor = mDiskCache.edit(key);
            if (editor != null) {
                out = editor.newOutputStream(0);
                if (value != null && value.length > 0) {
                    out.write(value);
                    out.flush();
                    editor.commit();
                } else {
                    editor.abort();
                }
            }
            mDiskCache.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            DiskLruUtils.closeQuietly(out);
        }
    }

private Drawable download(String imageUrl) {
        HttpURLConnection urlConnection = null;
        ByteArrayOutputStream bos = null;
        InputStream ins = null;
        try {
            final URL url = new URL(imageUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            ins = urlConnection.getInputStream();
            bos = new ByteArrayOutputStream();
            int b;
            while ((b = ins.read()) != -1) {
                bos.write(b);
            }
            bos.flush();
            byte[] bytes = bos.toByteArray();
            Bitmap bitmap = DiskLruUtils.bytes2Bitmap(bytes);
            String key = DiskLruUtils.hashKeyForDisk(imageUrl);
            Drawable drawable = DiskLruUtils.bitmap2Drawable(bitmap);
            //加入内存缓存
            // addDrawableToMemoryCache(key, drawable);
            //加入磁盘缓存
            addBitmapToDiskCache(key, bytes);
            return drawable;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            DiskLruUtils.closeQuietly(bos);
            DiskLruUtils.closeQuietly(ins);
        }
        return null;
    }

/**
     * 从缓存中移除
     *
     * @param key
     */
    public void removeCache(String key) {
        removeCacheFromMemory(key);
        removeCacheFromDisk(key);
    }

/**
     * 从内存缓存中移除
     *
     * @param key
     */
    public void removeCacheFromMemory(String key) {
        mMemoryCache.remove(key);
    }

/**
     * 从磁盘缓存中移除
     *
     * @param key
     */
    public void removeCacheFromDisk(String key) {
        try {
            mDiskCache.remove(key);
        } catch (Exception e) {
        }
    }

/**
     * 磁盘缓存大小
     *
     * @return
     */
    public long diskCacheSize() {

return mDiskCache.size();
    }

/**
     * 内存缓存大小
     *
     * @return
     */
    public long memoryCacheSize() {

return mMemoryCache.size();
    }

/**
     * 关闭磁盘缓存
     */
    public void closeDiskCache() {
        try {
            mDiskCache.close();
        } catch (Exception e) {
        }
    }

/**
     * 清理缓存
     */
    public void cleanCache() {
        cleanMemoryCCache();
        cleanDiskCache();
    }

/**
     * 清理磁盘缓存
     */
    public void cleanDiskCache() {
        try {
            mDiskCache.delete();
        } catch (Exception e) {
        }
    }

/**
     * 清理内存缓存
     */
    public void cleanMemoryCCache() {
        mMemoryCache.evictAll();
    }
}

ImageLoadManager.java

  1. public class ImageLoadManager {
  2. private LruCache<String, Drawable> mMemoryCache;//内存缓存
  3. private DiskLruCache mDiskCache;//磁盘缓存
  4. private static ImageLoadManager mInstance;//获取图片下载单例引用
  5.  
  6. /**
  7. * 构造器
  8. *
  9. * @param context
  10. */
  11. private ImageLoadManager(Context context) {
  12. int maxMemory = (int) Runtime.getRuntime().maxMemory();//获取系统分配给应用的总内存大小
  13. int mCacheSize = maxMemory / 8;//设置图片内存缓存占用八分之一
  14. mMemoryCache = new LruCache<String, Drawable>(mCacheSize) {
  15. //必须重写此方法,来测量Bitmap的大小
  16. @Override
  17. protected int sizeOf(String key, Drawable value) {
  18. if (value instanceof BitmapDrawable) {
  19. Bitmap bitmap = ((BitmapDrawable) value).getBitmap();
  20. return bitmap == null ? 0 : bitmap.getByteCount();
  21. }
  22. return super.sizeOf(key, value);
  23. }
  24. };
  25.  
  26. File cacheDir = context.getCacheDir();//指定的是数据的缓存地址
  27. long diskCacheSize = 1024 * 1024 * 30;//最多可以缓存多少字节的数据
  28. int appVersion = DiskLruUtils.getAppVersion(context);//指定当前应用程序的版本号
  29. int valueCount = 1;//指定同一个key可以对应多少个缓存文件
  30. try {
  31. mDiskCache = DiskLruCache.open(cacheDir, appVersion, valueCount, diskCacheSize);
  32. } catch (Exception ex) {
  33. }
  34. }
  35.  
  36. /**
  37. * 获取单例引用
  38. *
  39. * @return
  40. */
  41. public static ImageLoadManager getInstance(Context context) {
  42. ImageLoadManager inst = mInstance;
  43. if (inst == null) {
  44. synchronized (RequestManager.class) {
  45. inst = mInstance;
  46. if (inst == null) {
  47. inst = new ImageLoadManager(context.getApplicationContext());
  48. mInstance = inst;
  49. }
  50. }
  51. }
  52. return inst;
  53. }
  54.  
  55. public void disPlay(final ImageView imageView, String imageUrl) {
  56. //生成唯一key
  57. final String key = DiskLruUtils.hashKeyForDisk(imageUrl);
  58. //先从内存中读取
  59. Drawable drawableFromMemCache = getDrawableFromMemCache(key);
  60. if (drawableFromMemCache != null) {
  61. imageView.setImageDrawable(drawableFromMemCache);
  62. return;
  63. }
  64. Observable.just(imageUrl)
  65. .map(new Func1<String, Drawable>() {
  66. @Override
  67. public Drawable call(String imageUrl) { // 参数类型 String
  68. //从磁盘中读取
  69. Drawable drawableFromDiskCache = getDrawableFromDiskCache(key);
  70. if (drawableFromDiskCache != null) {
  71. return drawableFromDiskCache;
  72. }
  73. //网络下载
  74. return download(imageUrl); // 返回类型 Drawable
  75. }
  76. })
  77. .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
  78. .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
  79. .subscribe(new Action1<Drawable>() {
  80. @Override
  81. public void call(Drawable drawable) { // 参数类型 Drawable
  82. imageView.setImageDrawable(drawable);
  83. }
  84. });
  85. }
  86.  
  87. /**
  88. * 添加Drawable到内存缓存
  89. *
  90. * @param key
  91. * @param drawable
  92. */
  93. private void addDrawableToMemoryCache(String key, Drawable drawable) {
  94. if (getDrawableFromMemCache(key) == null && drawable != null) {
  95. mMemoryCache.put(key, drawable);
  96. }
  97. }
  98.  
  99. /**
  100. * 从内存缓存中获取一个Drawable
  101. *
  102. * @param key
  103. * @return
  104. */
  105. public Drawable getDrawableFromMemCache(String key) {
  106. return mMemoryCache.get(key);
  107. }
  108.  
  109. /**
  110. * 从磁盘缓存中获取一个Drawable
  111. *
  112. * @param key
  113. * @return
  114. */
  115. public Drawable getDrawableFromDiskCache(String key) {
  116. try {
  117. DiskLruCache.Snapshot snapShot = mDiskCache.get(key);
  118. if (snapShot != null) {
  119. InputStream is = snapShot.getInputStream(0);
  120. Bitmap bitmap = BitmapFactory.decodeStream(is);
  121. Drawable drawable = DiskLruUtils.bitmap2Drawable(bitmap);
  122. //从磁盘中读取到之后 加入内存缓存
  123. addDrawableToMemoryCache(key, drawable);
  124. return drawable;
  125. }
  126. } catch (IOException e) {
  127. e.printStackTrace();
  128. }
  129. return null;
  130. }
  131.  
  132. /**
  133. * 添加Bitmap到磁盘缓存
  134. *
  135. * @param key
  136. * @param value
  137. */
  138. private void addBitmapToDiskCache(String key, byte[] value) {
  139. OutputStream out = null;
  140. try {
  141. DiskLruCache.Editor editor = mDiskCache.edit(key);
  142. if (editor != null) {
  143. out = editor.newOutputStream(0);
  144. if (value != null && value.length > 0) {
  145. out.write(value);
  146. out.flush();
  147. editor.commit();
  148. } else {
  149. editor.abort();
  150. }
  151. }
  152. mDiskCache.flush();
  153. } catch (IOException e) {
  154. e.printStackTrace();
  155. } finally {
  156. DiskLruUtils.closeQuietly(out);
  157. }
  158. }
  159.  
  160. private Drawable download(String imageUrl) {
  161. HttpURLConnection urlConnection = null;
  162. ByteArrayOutputStream bos = null;
  163. InputStream ins = null;
  164. try {
  165. final URL url = new URL(imageUrl);
  166. urlConnection = (HttpURLConnection) url.openConnection();
  167. ins = urlConnection.getInputStream();
  168. bos = new ByteArrayOutputStream();
  169. int b;
  170. while ((b = ins.read()) != -1) {
  171. bos.write(b);
  172. }
  173. bos.flush();
  174. byte[] bytes = bos.toByteArray();
  175. Bitmap bitmap = DiskLruUtils.bytes2Bitmap(bytes);
  176. String key = DiskLruUtils.hashKeyForDisk(imageUrl);
  177. Drawable drawable = DiskLruUtils.bitmap2Drawable(bitmap);
  178. //加入内存缓存
  179. // addDrawableToMemoryCache(key, drawable);
  180. //加入磁盘缓存
  181. addBitmapToDiskCache(key, bytes);
  182. return drawable;
  183. } catch (IOException e) {
  184. e.printStackTrace();
  185. } finally {
  186. if (urlConnection != null) {
  187. urlConnection.disconnect();
  188. }
  189. DiskLruUtils.closeQuietly(bos);
  190. DiskLruUtils.closeQuietly(ins);
  191. }
  192. return null;
  193. }
  194.  
  195. /**
  196. * 从缓存中移除
  197. *
  198. * @param key
  199. */
  200. public void removeCache(String key) {
  201. removeCacheFromMemory(key);
  202. removeCacheFromDisk(key);
  203. }
  204.  
  205. /**
  206. * 从内存缓存中移除
  207. *
  208. * @param key
  209. */
  210. public void removeCacheFromMemory(String key) {
  211. mMemoryCache.remove(key);
  212. }
  213.  
  214. /**
  215. * 从磁盘缓存中移除
  216. *
  217. * @param key
  218. */
  219. public void removeCacheFromDisk(String key) {
  220. try {
  221. mDiskCache.remove(key);
  222. } catch (Exception e) {
  223. }
  224. }
  225.  
  226. /**
  227. * 磁盘缓存大小
  228. *
  229. * @return
  230. */
  231. public long diskCacheSize() {
  232.  
  233. return mDiskCache.size();
  234. }
  235.  
  236. /**
  237. * 内存缓存大小
  238. *
  239. * @return
  240. */
  241. public long memoryCacheSize() {
  242.  
  243. return mMemoryCache.size();
  244. }
  245.  
  246. /**
  247. * 关闭磁盘缓存
  248. */
  249. public void closeDiskCache() {
  250. try {
  251. mDiskCache.close();
  252. } catch (Exception e) {
  253. }
  254. }
  255.  
  256. /**
  257. * 清理缓存
  258. */
  259. public void cleanCache() {
  260. cleanMemoryCCache();
  261. cleanDiskCache();
  262. }
  263.  
  264. /**
  265. * 清理磁盘缓存
  266. */
  267. public void cleanDiskCache() {
  268. try {
  269. mDiskCache.delete();
  270. } catch (Exception e) {
  271. }
  272. }
  273.  
  274. /**
  275. * 清理内存缓存
  276. */
  277. public void cleanMemoryCCache() {
  278. mMemoryCache.evictAll();
  279. }
  280. }
  1. DiskLruUtils.java
final class DiskLruUtils {

/**
     * 关闭输入输出流
     */
    public static void closeQuietly(/*Auto*/Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (RuntimeException rethrown) {
                throw rethrown;
            } catch (Exception ignored) {
            }
        }
    }

/**
     * 获取versionCode
     */
    public static int getAppVersion(Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }

public static String hashKeyForDisk(String key) {
        String cacheKey;
        try {
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
            mDigest.update(key.getBytes());
            cacheKey = bytesToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            cacheKey = String.valueOf(key.hashCode());
        }
        return cacheKey;
    }

public static String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }

/**
     * Bitmap → bytes
     */
    public static byte[] bitmap2Bytes(Bitmap bm) {
        if (bm == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

/**
     * bytes → Bitmap
     */
    public static Bitmap bytes2Bitmap(byte[] bytes) {
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

/**
     * Drawable → Bitmap
     */
    public static Bitmap drawable2Bitmap(Drawable drawable) {
        if (drawable == null) {
            return null;
        }
        // 取 drawable 的长宽
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        // 取 drawable 的颜色格式
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        // 建立对应 bitmap
        Bitmap bitmap = Bitmap.createBitmap(w, h, config);
        // 建立对应 bitmap 的画布
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        // 把 drawable 内容画到画布中
        drawable.draw(canvas);
        return bitmap;
    }

/*
         * Bitmap → Drawable
         */
    public static Drawable bitmap2Drawable(Bitmap bm) {
        if (bm == null) {
            return null;
        }
        BitmapDrawable bd = new BitmapDrawable(bm);
        bd.setTargetDensity(bm.getDensity());
        return new BitmapDrawable(bm);
    }

}

DiskLruUtils.java

  1. final class DiskLruUtils {
  2.  
  3. /**
  4. * 关闭输入输出流
  5. */
  6. public static void closeQuietly(/*Auto*/Closeable closeable) {
  7. if (closeable != null) {
  8. try {
  9. closeable.close();
  10. } catch (RuntimeException rethrown) {
  11. throw rethrown;
  12. } catch (Exception ignored) {
  13. }
  14. }
  15. }
  16.  
  17. /**
  18. * 获取versionCode
  19. */
  20. public static int getAppVersion(Context context) {
  21. try {
  22. PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
  23. return info.versionCode;
  24. } catch (PackageManager.NameNotFoundException e) {
  25. e.printStackTrace();
  26. }
  27. return 1;
  28. }
  29.  
  30. public static String hashKeyForDisk(String key) {
  31. String cacheKey;
  32. try {
  33. final MessageDigest mDigest = MessageDigest.getInstance("MD5");
  34. mDigest.update(key.getBytes());
  35. cacheKey = bytesToHexString(mDigest.digest());
  36. } catch (NoSuchAlgorithmException e) {
  37. cacheKey = String.valueOf(key.hashCode());
  38. }
  39. return cacheKey;
  40. }
  41.  
  42. public static String bytesToHexString(byte[] bytes) {
  43. StringBuilder sb = new StringBuilder();
  44. for (int i = 0; i < bytes.length; i++) {
  45. String hex = Integer.toHexString(0xFF & bytes[i]);
  46. if (hex.length() == 1) {
  47. sb.append('0');
  48. }
  49. sb.append(hex);
  50. }
  51. return sb.toString();
  52. }
  53.  
  54. /**
  55. * Bitmap → bytes
  56. */
  57. public static byte[] bitmap2Bytes(Bitmap bm) {
  58. if (bm == null) {
  59. return null;
  60. }
  61. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  62. bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
  63. return baos.toByteArray();
  64. }
  65.  
  66. /**
  67. * bytes → Bitmap
  68. */
  69. public static Bitmap bytes2Bitmap(byte[] bytes) {
  70. return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
  71. }
  72.  
  73. /**
  74. * Drawable → Bitmap
  75. */
  76. public static Bitmap drawable2Bitmap(Drawable drawable) {
  77. if (drawable == null) {
  78. return null;
  79. }
  80. // 取 drawable 的长宽
  81. int w = drawable.getIntrinsicWidth();
  82. int h = drawable.getIntrinsicHeight();
  83. // 取 drawable 的颜色格式
  84. Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
  85. // 建立对应 bitmap
  86. Bitmap bitmap = Bitmap.createBitmap(w, h, config);
  87. // 建立对应 bitmap 的画布
  88. Canvas canvas = new Canvas(bitmap);
  89. drawable.setBounds(0, 0, w, h);
  90. // 把 drawable 内容画到画布中
  91. drawable.draw(canvas);
  92. return bitmap;
  93. }
  94.  
  95. /*
  96. * Bitmap → Drawable
  97. */
  98. public static Drawable bitmap2Drawable(Bitmap bm) {
  99. if (bm == null) {
  100. return null;
  101. }
  102. BitmapDrawable bd = new BitmapDrawable(bm);
  103. bd.setTargetDensity(bm.getDensity());
  104. return new BitmapDrawable(bm);
  105. }
  106.  
  107. }

总结:

以上就是基于Lru图片缓存简单实现

Android图片缓存之Lru算法(二)的更多相关文章

  1. Android图片缓存之Lru算法

    前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发 ...

  2. android图片缓存框架Android-Universal-Image-Loader(二)

    http://blog.csdn.net/king_is_everyone/article/details/35595515 这篇打算直接告诉大家怎么用吧,其实这个也不是很难的框架,大致使用过程如下: ...

  3. Android图片缓存之Bitmap详解

    前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...

  4. Android图片缓存之Glide进阶

    前言: 前面学习了Glide的简单使用(Android图片缓存之初识Glide),今天来学习一下Glide稍微复杂一点的使用. 图片缓存相关博客地址: Android图片缓存之Bitmap详解 And ...

  5. Android图片缓存之初识Glide

    前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...

  6. 安卓高级 Android图片缓存之初识Glide

    前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...

  7. Android图片缓存框架Glide

    Android图片缓存框架Glide Glide是Google提供的一个组件.它具有获取.解码和展示视频剧照.图片.动画等功能.它提供了灵活的API,帮助开发者将Glide应用在几乎任何网络协议栈中. ...

  8. Android图片缓存之初识Glide(三)

    前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...

  9. Android 图片缓存处理

    异步下载 / 本地缓存 异步下载 大家都知道,在Android应用中UI线程5秒没响应的话就会抛出无响应异常,对于远程获取大的资源来说,这种异常还是很容易就会抛出来的,那么怎么避免这种问题的产生.在a ...

随机推荐

  1. Linux学习-systemctl 针对 service 类型的配置文件

    systemctl 配置文件相关目录简介 现在我们知道服务的管理是透过 systemd,而 systemd 的配置文件大部分放置于 /usr/lib/systemd/system/ 目录内. 该目录的 ...

  2. selenium2截图ScreenShot的使用

    截图是做测试的基本技能,在有BUG的地方,截个图,保留失败的证据,也方便去重现BUG.所以,在自动化的过程中,也要能截图,也要能在我们想要截取的地方去截图,且能在错误产生时,自动的截图. 示例: 脚本 ...

  3. CF 219 D:Choosing Capital for Treeland(树形dp)

    D. Choosing Capital for Treeland 链接:http://codeforces.com/problemset/problem/219/D   The country Tre ...

  4. luogu1736 创意吃鱼法

    好的题解使人一下就懂啊-- s1[i][j]表示(i,j)最多向左(或右)延伸多少个格子,使这些格子中的数都是0(不包括(i,j)) s2[i][j]表示(i,j)最多向上延伸多少个格子,使这些格子中 ...

  5. 利用bochs调试Linux 0.11内核

    引导程序调试软件bochs,跟配套的linux0.11内核img下载地址分别是: http://sourceforge.net/projects/bochs/http://www.oldlinux.o ...

  6. EOJ Monthly 2018.4

    A. ultmaster 的小迷妹们 Time limit per test: 2.0 seconds Memory limit: 256 megabytes ultmaster 男神和他的小迷妹们准 ...

  7. Java判断浏览器是微信还是支付宝

    private static final String WX_AGENT = "micromessenger"; private static final String ALI_A ...

  8. PHP协程是通过生成器实现的,这里测试了PHP生成器的一些特性

    学习PHP的生成器,测试了一些特性.代码如下: function gen() { $name = (yield 'hello'); $nickname = (yield 'world'); yield ...

  9. 部署文件到IIS

    1.更改文件夹的权限 添加IIS_IUSR 右键属性-编辑-添加-高级-立即查找-添加IIS_IUSR .Everyone用户-勾选完全控制2.添加网站UI层-更改版本4.0-托管管道模式-经典3.网 ...

  10. HDU——2056Rectangles(几何计算)

    Rectangles Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...