首先解释一下为什么要用内存缓存,内存缓存好在哪里?
一个从网络下载下来的图片要在用户界面显示。不可能每一次打开都花费用户的流量去网上下载图片(并且下载需要时间,就会造成卡顿的现象),内存缓存主要运用在listview,recylerview等这种类型上,使加载图片时保证用户的操作流畅感。
缓存一般要做三层,首先就是内存缓存,内存缓存没有数据就向本地缓存拿取数据,本地缓存没有就拿取网络缓存。
这里直接分享一个内存缓存的工具类(使用强引用和软引用保证数据的缓存量和避免系统的OOM)
public class ImageCache { private static final int MAX_CAPACITY = 50;// 一级缓存的最大空间 private static final long DELAY_BEFORE_PURGE = 10 * 1000;// 定时清理缓存 // 0.75是加载因子为经验值,true则表示按照最近访问量的高低排序,false则表示按照插入顺序排序 private HashMap<String, Bitmap> mFirstLevelCache = new LinkedHashMap<String, Bitmap>( MAX_CAPACITY / 2, 0.75f, true) { protected boolean removeEldestEntry(Entry<String, Bitmap> eldest) { if (size() > MAX_CAPACITY) {// 当超过一级缓存阈值的时候,将老的值从一级缓存搬到二级缓存 mSecondLevelCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue())); return true; } return false; }; }; // 二级缓存,采用的是软应用,只有在内存吃紧的时候软应用才会被回收,有效的避免了oom private ConcurrentHashMap<String, SoftReference<Bitmap>> mSecondLevelCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>( MAX_CAPACITY / 2); /** * 放入缓存 * * @param url * @param value */ public void addBitmap2Cache(String url, Bitmap value) { if (value == null || url == null) { return; } synchronized (mFirstLevelCache) { mFirstLevelCache.put(url, value); } } /** * 从缓存中获取 * * @param url * @param */ public Bitmap getBitmapFromCache(String url) { Bitmap bitmap = null; bitmap = getFromFirstLevelCache(url);// 从一级缓存中拿 if (bitmap != null) { return bitmap; } bitmap = getFromSecondLevelCache(url);// 从二级缓存中拿 return bitmap; } /** * 从二级缓存中拿 * * @param url * @return */ private Bitmap getFromSecondLevelCache(String url) { Bitmap bitmap = null; SoftReference<Bitmap> softReference = mSecondLevelCache.get(url); if (softReference != null) { bitmap = softReference.get(); if (bitmap == null) {// 由于内存吃紧,软引用已经被gc回收了 mSecondLevelCache.remove(url); } } return bitmap; } /** * 从一级缓存中拿 * * @param url * @return */ private Bitmap getFromFirstLevelCache(String url) { Bitmap bitmap = null; synchronized (mFirstLevelCache) { bitmap = mFirstLevelCache.get(url); if (bitmap != null) {// 将最近访问的元素放到链的头部,提高下一次访问该元素的检索速度(LRU算法) mFirstLevelCache.remove(url); mFirstLevelCache.put(url, bitmap); } } return bitmap; } public void clear() { mFirstLevelCache.clear(); mSecondLevelCache.clear(); } }