图片的缓存

来源:互联网 发布:java策略模式实例 编辑:程序博客网 时间:2024/06/14 22:15
本博文为子墨原创,转载请注明出处!
http://blog.csdn.net/zimo2013/article/details/15108267
/** *  * @author zimo2013 * @see http://blog.csdn.net/zimo2013 * */public interface ICacheManager {public boolean addCacheBitmap(String key, Bitmap bitmap);public Bitmap getCacheBitmapByKey(String key);public void clear();public void remove(String key);}
/** *  * @author zimo2013 * @see http://blog.csdn.net/zimo2013 * * LruCache缓存,由于指定了该缓存的最大值,可以方便管理内存中的缓存图片, * 关键的方法,为sizeOf() 和   entryRemoved() * */class LruCacheManager implements ICacheManager{private static LruCacheManager manager;private static LruCache<String, Bitmap> lruCache;private LruCacheManager() {}/** * 静态方法,得到SDCardCacheManager实例化对象 *  * @return */static LruCacheManager getManager(LruCache<String, Bitmap> cache) {if (manager == null) {manager = new LruCacheManager();lruCache = cache;}return manager;}public Bitmap getCacheBitmapByKey(String name) {return lruCache.get(name);}public boolean addCacheBitmap(String name, Bitmap bitmap) {if (name != null && bitmap != null) {lruCache.put(name, bitmap);return true;        }return false;}@Overridepublic void clear() {//待实现}@Overridepublic void remove(String key) {//待实现}}
/** *  * @author zimo2013 * @see http://blog.csdn.net/zimo2013 * * 在抛出内存溢出之前,回收SoftReference中中引用的对象 * */class SoftRefManager implements ICacheManager{private static SoftRefManager manager;private HashMap<String, SoftReference<Bitmap>> map;private SoftRefManager() {map = new HashMap<String, SoftReference<Bitmap>>();}/** * 静态方法,得到SoftRefManager实例化对象 * @return */static SoftRefManager getManager() {if(manager == null){manager = new SoftRefManager(); }return manager;}/** * 根据name找到软引用指向的对象 * @param name * @return */public Bitmap getCacheBitmapByKey(String name){Bitmap bitmap = null;SoftReference<Bitmap> softRef = map.get(name);if(softRef != null){bitmap = softRef.get();if(bitmap == null){map.remove(name);}}return bitmap;}/** * 将制定的name-bitmap键值对添加至集合中 * @param name * @param bitmap */public boolean addCacheBitmap(String name, Bitmap bitmap){SoftReference<Bitmap> softRef = new SoftReference<Bitmap>(bitmap);map.put(name, softRef);return true;}@Overridepublic void clear() {}@Overridepublic void remove(String key) {}}
/** *  * @author zimo2013 * @see http://blog.csdn.net/zimo2013 * * 管理SDCard image的缓存 */class SDCardCacheManager implements ICacheManager{private final static String TAG = "SDCardCacheManager";private List<CachedFile> cachedList;private long currentSize;//当前缓存总大小private static SDCardCacheManager manager;private static File file;//缓存文件目录 private static long CAPACITY;//缓存文件总大小private static int LEVEL = 1;private static final int LEVEL_SAFE = 1;private static final int LEVEL_MAY_NOTSAFE = 2;private static final int LEVEL_NOTSAFE = 3;/** * 静态方法,得到SDCardCacheManager实例化对象 * @return */static SDCardCacheManager getManager() {if(manager == null){if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){System.out.println("SDCard不存在或者尚未申请sdcard读写权限!");}else{System.out.println("sdcard:"+Constants.EXT_PATH);file = new File(Constants.CACHE_DIR);CAPACITY = Constants.CAPACITY;manager = new SDCardCacheManager();}}return manager;}/** * 私有化的构造函数,完成缓存文件的遍历,初始化集合 */private SDCardCacheManager() {cachedList = new ArrayList<CachedFile>();//updateExternalLevel();if (!file.exists()) {file.mkdir();return;}for (File f : file.listFiles()) {//循环遍历图片if (f.isFile()) {CachedFile cachedFile = new CachedFile(f.getName(), f.length(),f.lastModified());currentSize += f.length();cachedList.add(cachedFile);}}}/** * 将指定的key-obj键值对保存至SDCard */@Overridepublic boolean addCacheBitmap(String key, Bitmap bitmap){if(LEVEL > LEVEL_MAY_NOTSAFE){System.out.println("外设存储不足, 暂不保存缓存");return false;}File f = new File(file, key);if (f.exists()) {//如果该缓存文件已经存在return true;}FileOutputStream fos = null;try {fos = new FileOutputStream(f);bitmap.compress(CompressFormat.PNG, 100, fos);currentSize += f.length();System.out.println("sdcard111"+f);CachedFile cachedFile = new CachedFile(key, f.length(),f.lastModified());cachedList.add(cachedFile);if(LEVEL > LEVEL_SAFE){updateExternalLevel();}if (currentSize > CAPACITY) {clear();}} catch (Exception e) {e.printStackTrace();}finally{if(fos != null){try {fos.close();System.out.println("sd流关闭成功");fos = null;} catch (IOException e) {e.printStackTrace();}}}return true;}/** * 读取缓存目录中,指定name的bitmap对象 * @param name * @return */@Overridepublic Bitmap getCacheBitmapByKey(String key) {Bitmap bitmap = null;for (CachedFile cachedFile : cachedList) {if (cachedFile.getName().equals(key)) {File f = new File(file, key);if(f.exists()){f.setLastModified(System.currentTimeMillis());//更新file时间bitmap = BitmapFactory.decodeFile(f.getAbsolutePath());System.out.println("sdcard命中:"+key);}return bitmap;}}return bitmap;}@Overridepublic void remove(String key) {if(key == null){System.out.println("key不能为空");return;}//待开发}/** * 清理缓存,当缓存容量超过指定CAPACITY时执行 */@Overridepublic void clear() {Collections.sort(cachedList);int end = cachedList.size();int start = end*2 / 3; // 清理最久未被使用的1/3ListIterator<CachedFile> it = cachedList.listIterator(start);while(it.hasNext()){CachedFile cachedFile = it.next();System.out.println("清理文件"+cachedFile.getName());new File(file, cachedFile.getName()).delete();currentSize -= cachedFile.getLength();it.remove();}}public Object getCacheFileByKey(String key) {Object obj = null;for (CachedFile cachedFile : cachedList) {if (cachedFile.getName().equals(key)) {return cachedFile;}}return obj;}/** * 更新外部存储剩余容量等级<br/> * LEVEL_SAFE = 1 <br/> * LEVEL_MAY_NOTSAFE = 2 <br/> * LEVEL_NOTSAFE = 3<br/> */public void updateExternalLevel(){StatFs statFs = new StatFs(Constants.EXT_PATH);int availBlock = statFs.getAvailableBlocks();int blockSize = statFs.getBlockSize();long availByte = availBlock*blockSize;Log.i(TAG, "availByte = "+availByte);if(availBlock*blockSize > 1024*1024*30){//30MLEVEL = LEVEL_SAFE;}else if(availBlock*blockSize > 1024*1024*5){//5MLEVEL = LEVEL_MAY_NOTSAFE;}else{LEVEL = LEVEL_NOTSAFE;}}}
/** *  * @author zimo2013 * @see http://blog.csdn.net/zimo2013 * */public class AppCacheManager implements ICacheManager {private final static String TAG = "AppCacheManager";private static ICacheManager manager;/** * 在使用sdcard时,应该首先判断sdcard是否存在且挂载可用,如果使用只需要判断 if(sdManager != null);  */private static SDCardCacheManager sdManager;private static SoftRefManager refManager;private static LruCacheManager lruManager;private AppCacheManager() {}public static ICacheManager getManager() {if (manager == null) {manager = new AppCacheManager();sdManager = SDCardCacheManager.getManager();refManager = SoftRefManager.getManager();lruManager = LruCacheManager.getManager(new LruCacheList(Constants.LRU_MAXSIZE));// 相应manager缓存管理对象}return manager;}private static class LruCacheList extends LruCache<String, Bitmap> {public LruCacheList(int maxSize) {super(maxSize);}@Overrideprotected int sizeOf(String key, Bitmap value) {return value.getRowBytes() * value.getHeight();}@Overrideprotected void entryRemoved(boolean evicted, String key,Bitmap oldValue, Bitmap newValue) {if (evicted) {LogUtil.i(TAG, "缓存被挤出:"+key);//如果sdCard存在,写入sdCardif(sdManager != null){sdManager.addCacheBitmap(key, oldValue);}// 2.添加至软引用集合refManager.addCacheBitmap(key, oldValue);}}}/** * 将key-obj键值对存入 */@Overridepublic boolean addCacheBitmap(String key, Bitmap bitmap) {if (key == null || bitmap == null) {System.out.println("key=null || obj=null");return false;}if(sdManager != null){//如果sdcard存在可用,存入sdcardsdManager.addCacheBitmap(key, bitmap);}lruManager.addCacheBitmap(key, bitmap);return true;}/** * 得到缓存对象根据key,如果返回为null需要访问网络获取数据 */@Overridepublic Bitmap getCacheBitmapByKey(String key) {if(key == null){return null;}Bitmap bitmap = lruManager.getCacheBitmapByKey(key);if (bitmap == null) {bitmap = refManager.getCacheBitmapByKey(key);if (bitmap==null && sdManager!=null) {//从sdcard中取数据bitmap = sdManager.getCacheBitmapByKey(key);}}if (bitmap != null) {lruManager.addCacheBitmap(key, bitmap);}return bitmap;}@Overridepublic void clear() {lruManager.clear();refManager.clear();if(sdManager != null){sdManager.clear();}}@Overridepublic void remove(String key) {lruManager.remove(key);refManager.remove(key);if(sdManager != null){sdManager.remove(key);}}}
/** * 缓存文件bean * */public class CachedFile implements Comparable<CachedFile> {private String name;private long length;private long modTime;public CachedFile() {}public CachedFile(String name, long length, long modTime) {this.name = name;this.length = length;this.modTime = modTime;}public String getName() {return name;}public void setName(String name) {this.name = name;}public long getLength() {return length;}public void setLength(long length) {this.length = length;}public long getModTime() {return modTime;}public void setModTime(long modTime) {this.modTime = modTime;}@Overridepublic int compareTo(CachedFile another) {if(this.modTime > another.modTime)return -1;return 1;}}
public class Constants {public final static String EXT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();public final static int LRU_MAXSIZE = 8 * 1024 * 1024;public final static int CAPACITY = 10 * 1024 * 1024;public final static String CACHE_DIR = EXT_PATH + "/cache";}
0 0
原创粉丝点击