Android缓存字符串,对象等其他数据的工具类

jopen 10年前

    ACache是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。

1、它可以缓存什么东西?

普通的字符串、json、序列化的java对象,和 字节数字。

2、它有什么特色?

特色主要是:

1:轻,轻到只有一个JAVA文件。

2:可配置,可以配置缓存路径,缓存大小,缓存数量等。

3:可以设置缓存超时时间,缓存超时自动失效,并被删除。

4:多进程的支持。

下面附上完整代码:

public class ACache {      public static final int TIME_HOUR = 60 * 60;      public static final int TIME_DAY = TIME_HOUR * 24;      private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb      private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量      private static Map<String, ACache> mInstanceMap = new HashMap<String, ACache>();      private ACacheManager mCache;         public static ACache get(Context ctx) {          return get(ctx, "ACache");      }         public static ACache get(Context ctx, String cacheName) {          File f = new File(ctx.getCacheDir(), cacheName);          return get(f, MAX_SIZE, MAX_COUNT);      }         public static ACache get(File cacheDir) {          return get(cacheDir, MAX_SIZE, MAX_COUNT);      }         public static ACache get(Context ctx, long max_zise, int max_count) {          File f = new File(ctx.getCacheDir(), "ACache");          return get(f, max_zise, max_count);      }         public static ACache get(File cacheDir, long max_zise, int max_count) {          ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());          if (manager == null) {              manager = new ACache(cacheDir, max_zise, max_count);              mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);          }          return manager;      }         private static String myPid() {          return "_" + android.os.Process.myPid();      }         private ACache(File cacheDir, long max_size, int max_count) {          if (!cacheDir.exists() && !cacheDir.mkdirs()) {              throw new RuntimeException("can't make dirs in "                      + cacheDir.getAbsolutePath());          }          mCache = new ACacheManager(cacheDir, max_size, max_count);      }         // =======================================      // ============ String数据 读写 ==============      // =======================================      /**       * 保存 String数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的String数据       */      public void put(String key, String value) {          File file = mCache.newFile(key);          BufferedWriter out = null;          try {              out = new BufferedWriter(new FileWriter(file), 1024);              out.write(value);          } catch (IOException e) {              e.printStackTrace();          } finally {              if (out != null) {                  try {                      out.flush();                      out.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }              mCache.put(file);          }      }         /**       * 保存 String数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的String数据       * @param saveTime       *            保存的时间,单位:秒       */      public void put(String key, String value, int saveTime) {          put(key, Utils.newStringWithDateInfo(saveTime, value));      }         /**       * 读取 String数据       *        * @param key       * @return String 数据       */      public String getAsString(String key) {          File file = mCache.get(key);          if (!file.exists())              return null;          boolean removeFile = false;          BufferedReader in = null;          try {              in = new BufferedReader(new FileReader(file));              String readString = "";              String currentLine;              while ((currentLine = in.readLine()) != null) {                  readString += currentLine;              }              if (!Utils.isDue(readString)) {                  return Utils.clearDateInfo(readString);              } else {                  removeFile = true;                  return null;              }          } catch (IOException e) {              e.printStackTrace();              return null;          } finally {              if (in != null) {                  try {                      in.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }              if (removeFile)                  remove(key);          }      }         // =======================================      // ============= JSONObject 数据 读写 ==============      // =======================================      /**       * 保存 JSONObject数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的JSON数据       */      public void put(String key, JSONObject value) {          put(key, value.toString());      }         /**       * 保存 JSONObject数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的JSONObject数据       * @param saveTime       *            保存的时间,单位:秒       */      public void put(String key, JSONObject value, int saveTime) {          put(key, value.toString(), saveTime);      }         /**       * 读取JSONObject数据       *        * @param key       * @return JSONObject数据       */      public JSONObject getAsJSONObject(String key) {          String JSONString = getAsString(key);          try {              JSONObject obj = new JSONObject(JSONString);              return obj;          } catch (Exception e) {              e.printStackTrace();              return null;          }      }         // =======================================      // ============ JSONArray 数据 读写 =============      // =======================================      /**       * 保存 JSONArray数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的JSONArray数据       */      public void put(String key, JSONArray value) {          put(key, value.toString());      }         /**       * 保存 JSONArray数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的JSONArray数据       * @param saveTime       *            保存的时间,单位:秒       */      public void put(String key, JSONArray value, int saveTime) {          put(key, value.toString(), saveTime);      }         /**       * 读取JSONArray数据       *        * @param key       * @return JSONArray数据       */      public JSONArray getAsJSONArray(String key) {          String JSONString = getAsString(key);          try {              JSONArray obj = new JSONArray(JSONString);              return obj;          } catch (Exception e) {              e.printStackTrace();              return null;          }      }         // =======================================      // ============== byte 数据 读写 =============      // =======================================      /**       * 保存 byte数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的数据       */      public void put(String key, byte[] value) {          File file = mCache.newFile(key);          FileOutputStream out = null;          try {              out = new FileOutputStream(file);              out.write(value);          } catch (Exception e) {              e.printStackTrace();          } finally {              if (out != null) {                  try {                      out.flush();                      out.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }              mCache.put(file);          }      }         /**       * 保存 byte数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的数据       * @param saveTime       *            保存的时间,单位:秒       */      public void put(String key, byte[] value, int saveTime) {          put(key, Utils.newByteArrayWithDateInfo(saveTime, value));      }         /**       * 获取 byte 数据       *        * @param key       * @return byte 数据       */      public byte[] getAsBinary(String key) {          RandomAccessFile RAFile = null;          boolean removeFile = false;          try {              File file = mCache.get(key);              if (!file.exists())                  return null;              RAFile = new RandomAccessFile(file, "r");              byte[] byteArray = new byte[(int) RAFile.length()];              RAFile.read(byteArray);              if (!Utils.isDue(byteArray)) {                  return Utils.clearDateInfo(byteArray);              } else {                  removeFile = true;                  return null;              }          } catch (Exception e) {              e.printStackTrace();              return null;          } finally {              if (RAFile != null) {                  try {                      RAFile.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }              if (removeFile)                  remove(key);          }      }         // =======================================      // ============= 序列化 数据 读写 ===============      // =======================================      /**       * 保存 Serializable数据 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的value       */      public void put(String key, Serializable value) {          put(key, value, -1);      }         /**       * 保存 Serializable数据到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的value       * @param saveTime       *            保存的时间,单位:秒       */      public void put(String key, Serializable value, int saveTime) {          ByteArrayOutputStream baos = null;          ObjectOutputStream oos = null;          try {              baos = new ByteArrayOutputStream();              oos = new ObjectOutputStream(baos);              oos.writeObject(value);              byte[] data = baos.toByteArray();              if (saveTime != -1) {                  put(key, data, saveTime);              } else {                  put(key, data);              }          } catch (Exception e) {              e.printStackTrace();          } finally {              try {                  oos.close();              } catch (IOException e) {              }          }      }         /**       * 读取 Serializable数据       *        * @param key       * @return Serializable 数据       */      public Object getAsObject(String key) {          byte[] data = getAsBinary(key);          if (data != null) {              ByteArrayInputStream bais = null;              ObjectInputStream ois = null;              try {                  bais = new ByteArrayInputStream(data);                  ois = new ObjectInputStream(bais);                  Object reObject = ois.readObject();                  return reObject;              } catch (Exception e) {                  e.printStackTrace();                  return null;              } finally {                  try {                      if (bais != null)                          bais.close();                  } catch (IOException e) {                      e.printStackTrace();                  }                  try {                      if (ois != null)                          ois.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }          }          return null;         }         // =======================================      // ============== bitmap 数据 读写 =============      // =======================================      /**       * 保存 bitmap 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的bitmap数据       */      public void put(String key, Bitmap value) {          put(key, Utils.Bitmap2Bytes(value));      }         /**       * 保存 bitmap 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的 bitmap 数据       * @param saveTime       *            保存的时间,单位:秒       */      public void put(String key, Bitmap value, int saveTime) {          put(key, Utils.Bitmap2Bytes(value), saveTime);      }         /**       * 读取 bitmap 数据       *        * @param key       * @return bitmap 数据       */      public Bitmap getAsBitmap(String key) {          if (getAsBinary(key) == null) {              return null;          }          return Utils.Bytes2Bimap(getAsBinary(key));      }         // =======================================      // ============= drawable 数据 读写 =============      // =======================================      /**       * 保存 drawable 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的drawable数据       */      public void put(String key, Drawable value) {          put(key, Utils.drawable2Bitmap(value));      }         /**       * 保存 drawable 到 缓存中       *        * @param key       *            保存的key       * @param value       *            保存的 drawable 数据       * @param saveTime       *            保存的时间,单位:秒       */      public void put(String key, Drawable value, int saveTime) {          put(key, Utils.drawable2Bitmap(value), saveTime);      }         /**       * 读取 Drawable 数据       *        * @param key       * @return Drawable 数据       */      public Drawable getAsDrawable(String key) {          if (getAsBinary(key) == null) {              return null;          }          return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key)));      }         /**       * 获取缓存文件       *        * @param key       * @return value 缓存的文件       */      public File file(String key) {          File f = mCache.newFile(key);          if (f.exists())              return f;          return null;      }         /**       * 移除某个key       *        * @param key       * @return 是否移除成功       */      public boolean remove(String key) {          return mCache.remove(key);      }         /**       * 清除所有数据       */      public void clear() {          mCache.clear();      }         /**       * @title 缓存管理器       * @version 1.0       */      public class ACacheManager {          private final AtomicLong cacheSize;          private final AtomicInteger cacheCount;          private final long sizeLimit;          private final int countLimit;          private final Map<File, Long> lastUsageDates = Collections                  .synchronizedMap(new HashMap<File, Long>());          protected File cacheDir;             private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {              this.cacheDir = cacheDir;              this.sizeLimit = sizeLimit;              this.countLimit = countLimit;              cacheSize = new AtomicLong();              cacheCount = new AtomicInteger();              calculateCacheSizeAndCacheCount();          }             /**           * 计算 cacheSize和cacheCount           */          private void calculateCacheSizeAndCacheCount() {              new Thread(new Runnable() {                  @Override                  public void run() {                      int size = 0;                      int count = 0;                      File[] cachedFiles = cacheDir.listFiles();                      if (cachedFiles != null) {                          for (File cachedFile : cachedFiles) {                              size += calculateSize(cachedFile);                              count += 1;                              lastUsageDates.put(cachedFile,                                      cachedFile.lastModified());                          }                          cacheSize.set(size);                          cacheCount.set(count);                      }                  }              }).start();          }             private void put(File file) {              int curCacheCount = cacheCount.get();              while (curCacheCount + 1 > countLimit) {                  long freedSize = removeNext();                  cacheSize.addAndGet(-freedSize);                     curCacheCount = cacheCount.addAndGet(-1);              }              cacheCount.addAndGet(1);                 long valueSize = calculateSize(file);              long curCacheSize = cacheSize.get();              while (curCacheSize + valueSize > sizeLimit) {                  long freedSize = removeNext();                  curCacheSize = cacheSize.addAndGet(-freedSize);              }              cacheSize.addAndGet(valueSize);                 Long currentTime = System.currentTimeMillis();              file.setLastModified(currentTime);              lastUsageDates.put(file, currentTime);          }             private File get(String key) {              File file = newFile(key);              Long currentTime = System.currentTimeMillis();              file.setLastModified(currentTime);              lastUsageDates.put(file, currentTime);                 return file;          }             private File newFile(String key) {              return new File(cacheDir, key.hashCode() + "");          }             private boolean remove(String key) {              File image = get(key);              return image.delete();          }             private void clear() {              lastUsageDates.clear();              cacheSize.set(0);              File[] files = cacheDir.listFiles();              if (files != null) {                  for (File f : files) {                      f.delete();                  }              }          }             /**           * 移除旧的文件           *            * @return           */          private long removeNext() {              if (lastUsageDates.isEmpty()) {                  return 0;              }                 Long oldestUsage = null;              File mostLongUsedFile = null;              Set<Entry<File, Long>> entries = lastUsageDates.entrySet();              synchronized (lastUsageDates) {                  for (Entry<File, Long> entry : entries) {                      if (mostLongUsedFile == null) {                          mostLongUsedFile = entry.getKey();                          oldestUsage = entry.getValue();                      } else {                          Long lastValueUsage = entry.getValue();                          if (lastValueUsage < oldestUsage) {                              oldestUsage = lastValueUsage;                              mostLongUsedFile = entry.getKey();                          }                      }                  }              }                 long fileSize = calculateSize(mostLongUsedFile);              if (mostLongUsedFile.delete()) {                  lastUsageDates.remove(mostLongUsedFile);              }              return fileSize;          }             private long calculateSize(File file) {              return file.length();          }      }         /**       * @title 时间计算工具类       * @version 1.0       */      private static class Utils {             /**           * 判断缓存的String数据是否到期           *            * @param str           * @return true:到期了 false:还没有到期           */          private static boolean isDue(String str) {              return isDue(str.getBytes());          }             /**           * 判断缓存的byte数据是否到期           *            * @param data           * @return true:到期了 false:还没有到期           */          private static boolean isDue(byte[] data) {              String[] strs = getDateInfoFromDate(data);              if (strs != null && strs.length == 2) {                  String saveTimeStr = strs[0];                  while (saveTimeStr.startsWith("0")) {                      saveTimeStr = saveTimeStr                              .substring(1, saveTimeStr.length());                  }                  long saveTime = Long.valueOf(saveTimeStr);                  long deleteAfter = Long.valueOf(strs[1]);                  if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {                      return true;                  }              }              return false;          }             private static String newStringWithDateInfo(int second, String strInfo) {              return createDateInfo(second) + strInfo;          }             private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) {              byte[] data1 = createDateInfo(second).getBytes();              byte[] retdata = new byte[data1.length + data2.length];              System.arraycopy(data1, 0, retdata, 0, data1.length);              System.arraycopy(data2, 0, retdata, data1.length, data2.length);              return retdata;          }             private static String clearDateInfo(String strInfo) {              if (strInfo != null && hasDateInfo(strInfo.getBytes())) {                  strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1,                          strInfo.length());              }              return strInfo;          }             private static byte[] clearDateInfo(byte[] data) {              if (hasDateInfo(data)) {                  return copyOfRange(data, indexOf(data, mSeparator) + 1,                          data.length);              }              return data;          }             private static boolean hasDateInfo(byte[] data) {              return data != null && data.length > 15 && data[13] == '-'                      && indexOf(data, mSeparator) > 14;          }             private static String[] getDateInfoFromDate(byte[] data) {              if (hasDateInfo(data)) {                  String saveDate = new String(copyOfRange(data, 0, 13));                  String deleteAfter = new String(copyOfRange(data, 14,                          indexOf(data, mSeparator)));                  return new String[] { saveDate, deleteAfter };              }              return null;          }             private static int indexOf(byte[] data, char c) {              for (int i = 0; i < data.length; i++) {                  if (data[i] == c) {                      return i;                  }              }              return -1;          }             private static byte[] copyOfRange(byte[] original, int from, int to) {              int newLength = to - from;              if (newLength < 0)                  throw new IllegalArgumentException(from + " > " + to);              byte[] copy = new byte[newLength];              System.arraycopy(original, from, copy, 0,                      Math.min(original.length - from, newLength));              return copy;          }             private static final char mSeparator = ' ';             private static String createDateInfo(int second) {              String currentTime = System.currentTimeMillis() + "";              while (currentTime.length() < 13) {                  currentTime = "0" + currentTime;              }              return currentTime + "-" + second + mSeparator;          }             /*           * Bitmap → byte[]           */          private static byte[] Bitmap2Bytes(Bitmap bm) {              if (bm == null) {                  return null;              }              ByteArrayOutputStream baos = new ByteArrayOutputStream();              bm.compress(Bitmap.CompressFormat.PNG, 100, baos);              return baos.toByteArray();          }             /*           * byte[] → Bitmap           */          private static Bitmap Bytes2Bimap(byte[] b) {              if (b.length == 0) {                  return null;              }              return BitmapFactory.decodeByteArray(b, 0, b.length);          }             /*           * Drawable → Bitmap           */          private 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           */          @SuppressWarnings("deprecation")          private static Drawable bitmap2Drawable(Bitmap bm) {              if (bm == null) {                  return null;              }              return new BitmapDrawable(bm);          }      }     }
来自:http://my.oschina.net/u/1471093/blog/345946