/* * Copyright (C) 2010 mAPPn.Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mappn.gfan.common.util; import java.io.File; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import android.graphics.Bitmap; import android.os.Environment; import android.os.Process; import com.mappn.gfan.Constants; /** * Cache Manager * * For caching something like drawables, objects... * * @author andrew.wang * */ public class CacheManager { private static CacheManager mInstance; // the max cached icon in the SD-Card private static final int MAX_IMAGE_IN_SDCARD = 100; // cache in the memory private LinkedHashMap<String, Bitmap> mDrawableMap = new LinkedHashMap<String, Bitmap>(); private SoftReference<LinkedHashMap<String, Bitmap>> mDrawableCache = new SoftReference<LinkedHashMap<String, Bitmap>>(mDrawableMap); private ArrayList<String> mNewIcons = new ArrayList<String>(); private CacheManager() { // loadIconsFromSDCard(); } public static CacheManager getInstance() { if (mInstance == null) { mInstance = new CacheManager(); } return mInstance; } /** * Get the icon list from memory cache */ private LinkedHashMap<String, Bitmap> getMemoCache() { if (mDrawableCache == null) { mDrawableCache = new SoftReference<LinkedHashMap<String, Bitmap>>(mDrawableMap); return mDrawableMap; } return mDrawableCache.get(); } /** * Check whether the drawable had been cached * * @param key * drawable uri * @return ture : exist false : not exist */ public boolean existsDrawable(String key) { // fetch the drawable from memory HashMap<String, Bitmap> memoCache = getMemoCache(); if (memoCache.containsKey(StringUtils.getFileNameFromUrl(key))) return true; return false; } /** * 开始缓存图片 */ public synchronized void cacheDrawable(String url, Bitmap image) { if (image == null) { return; } // put the icon in the memory LinkedHashMap<String, Bitmap> memoCache = getMemoCache(); if (memoCache == null) { return; } String key = StringUtils.getFileNameFromUrl(url); if(memoCache.size() < MAX_IMAGE_IN_SDCARD) { memoCache.put(key, image); return; } // reach here means L1 is full, reorder current stack Iterator<String> iterator = memoCache.keySet().iterator(); if (iterator.hasNext()) { // recycle the bitmap String oldBitmapUrl = (String) iterator.next(); memoCache.remove(oldBitmapUrl); // reorder the new image into L1 cache stack memoCache.put(key, image); } return; } /** * 从缓存中获取图片 * @param url 图片的HTTP资源的地址 */ public Bitmap getDrawableFromCache(String url) { // retrieve bitmap from cache final String urlFileName = StringUtils.getFileNameFromUrl(url); HashMap<String, Bitmap> memoCache = getMemoCache(); return memoCache.get(urlFileName); } // /** // * 将缓存图片存入SD卡 // */ // public void close() { // // // check the sd-card status // if (!Utils.isSdcardWritable()) { // clearFromMemory(); // Utils.D("save icons failed because sd card is not writable"); // return; // } // // new Thread() { // // @Override // public void run() { // // make this thread in background priority // setPriority(Process.THREAD_PRIORITY_BACKGROUND); // // File cacheDirectory = new File(Environment.getExternalStorageDirectory(), // Constants.IMAGE_CACHE_DIR); // // if (!cacheDirectory.exists()) { // Utils.V("cache dir not exist, make it immediately success"); // if(cacheDirectory.mkdirs()) { // Utils.V("cache dir not exist, make it immediately success"); // // HashMap<String, Bitmap> memoCache = getMemoCache(); // if (memoCache != null) { // final int length = mNewIcons.size(); // try { // for (int i = 0; i < length; i++) { // String key = mNewIcons.get(i); // final Bitmap bmp = memoCache.get(key); // if (bmp == null) { // continue; // } // FileOutputStream fos = null; // File file = new File(cacheDirectory, key); // if (file.exists()) { // continue; // } // fos = new FileOutputStream(file); // bmp.compress(CompressFormat.PNG, 100, fos); // fos.close(); // } // } catch (FileNotFoundException e) { // Utils.D("save icon fail because make file error", e); // } catch (IOException e) { // Utils.D("save icon fail because IOException", e); // } // } // } else { // Utils.V("cache dir not exist, make it immediately fail"); // } // } // // clear all the cache // clearFromMemory(); // } // }.start(); // } // /* // * 从SD卡加载缓存图片 // */ // private void loadIconsFromSDCard() { // // // check the sd-card status // if (!Utils.isSdcardReadable()) { // Utils.V("load icons failed because sd card is not readable"); // return; // } // // new Thread() { // @Override // public void run() { // // make this thread in background priority // setPriority(Process.THREAD_PRIORITY_BACKGROUND); // // File cacheDirectory = new File(Environment.getExternalStorageDirectory(), // Constants.IMAGE_CACHE_DIR); // if (cacheDirectory.exists()) { // File[] files = cacheDirectory.listFiles(); // int length = files.length; // if (length > MAX_IMAGE_IN_SDCARD) { // // 防止缓存文件冗余,清除超过最大缓存数的文件 // length = MAX_IMAGE_IN_SDCARD; // for (int i = length, len = files.length; i < len; i++) { // files[i].delete(); // } // } // // HashMap<String, Bitmap> memoCache = getMemoCache(); // if (memoCache == null) { // return; // } // synchronized (CacheManager.this) { // try { // for (int i = 0; i < length; i++) { // final String fileName = files[i].getName(); // Bitmap bmp = BitmapFactory.decodeFile(files[i].getAbsolutePath()); // memoCache.put(fileName, bmp); // } // } catch (OutOfMemoryError e) { // Utils.W("load icon from sd card occur OOM error"); // } // } // } // } // }.start(); // } /** * 当内存不足时清除所有缓存包括应用退出时 */ public void clearFromMemory() { if (mNewIcons != null) { mNewIcons.clear(); } if (mDrawableMap != null) { mDrawableMap.clear(); mDrawableMap = null; } if (mDrawableCache != null) { mDrawableCache.clear(); mDrawableCache = null; } mInstance = null; } /** * 从磁盘清除缓存 */ public void clearFromFile() { Thread clearTask = new Thread() { @Override public void run() { File cacheDirectory = new File(Environment.getExternalStorageDirectory(), Constants.IMAGE_CACHE_DIR); if (cacheDirectory.exists()) { File[] files = cacheDirectory.listFiles(); for (File file : files) { file.delete(); } } } }; clearTask.setPriority(Process.THREAD_PRIORITY_BACKGROUND); clearTask.start(); } }