ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
**(一):写在前面的话**  接着上一篇继续更新,上一篇文章已经把FastDev4Android项目列表下拉刷新组件(PullToRefreshListView)组件做了讲解和使用。今天项目更新是得数据缓存器(ACache)的详解和使用。  **(二):功能介绍**  2.1:基本介绍  ACache项目是我去年在Github上面发现的一个开源项目,首先感谢作者,感谢Github开源的力量。ACache是一个比较轻量级的数据缓存管理器(一个类ACache.java)解决问题,所以学习起来就非常简单,在中小型项目中可以较好的去使用。ACache使用采用手机包名路径下文件数据保存方式进行数据缓存,同时可以自定义设置数据缓存的路径,缓存的文件大小,以及缓存的文件数量以及相应的缓存过期时间。下面我们来看一下整个类中相应的方法和变量以及常量,这样对整个类有一个直观的了解。  ![](https://box.kancloud.cn/2016-01-18_569c8eb06f7a7.jpg)  ![](https://box.kancloud.cn/2016-01-18_569c8eb085870.jpg)  查看以上各种方法,我们可以知道ACache给我们提供了文本数据,JSON格式数据,图片等信息缓存,当然我们也可以通过实际的项目情况,对该类进行其他格式数据的扩展。  2.2:ACache流程  ACache请求处理流程  ![](https://box.kancloud.cn/2016-01-18_569c8eb0990da.jpg)  **(三):核心方法介绍**  3.1:相关配置数据设置 ~~~ public static final int TIME_HOUR = 60 * 60; //缓存一个小时 public static final int TIME_MINUTE = 60; //混存一分钟 public static final int TIME_DAY = TIME_HOUR * 12; //缓存一个白天 12个小时 private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量 ~~~ 以上可以自定义设置缓存时间,缓存文件大小和限制存放数据的数量等信息  3.2:静态获取ACache对象实现方法 ~~~ public static ACache get(Context ctx) public static ACache get(Context ctx, String cacheName) public static ACache get(File cacheDir) public static ACache get(Context ctx, long max_zise, int max_count) ~~~ 使用者可以根据不同的参数分别获取ACache管理对象。  3.3:ACache对象创建方法:  ①:对象获取 ~~~ 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; } ~~~ 根据以上代码可以知道在创建ACache对象的时候,会先通过Map Cache缓存中去查找是否已经存在该对象,有直接返回,如果不存在那么进行创建对象实例(通过new ACache(xxx,xx,xx)),然后保存一份到Map缓存中。  ②:对象创建 ~~~ 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); } ~~~ 以上代码可以得知最终我们使用的管理器就是ACacheManager实例,在这边进行缓存器的初始化(文件路径,缓存数量,缓存大小)以及数据最终保存和获取。那么最后我们来看一下整个ACacheManger的实现代码吧: ~~~ 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<Map.Entry<File, Long>> entries = lastUsageDates.entrySet(); synchronized (lastUsageDates) { for (Map.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(); } } ~~~ **(四):使用介绍**  我们在使用该工具的时候,很简单,获取对象实例,做put和get操作即可  ACache mACache=ACache.get(Contenxt) 默认获取方式,或者可以采用另外几个静态获取方法也可以,下面我们来看一下具体实现。 ~~~ private Button save_cache; private Button query_cache; private EditText edit_cache; private TextView tv_cache; private ACache mAcache; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sp_cache_layout); save_cache=(Button)this.findViewById(R.id.save_cache); query_cache=(Button)this.findViewById(R.id.query_cache); edit_cache=(EditText)this.findViewById(R.id.edit_cache); tv_cache=(TextView)this.findViewById(R.id.tv_cache); mAcache=ACache.get(this); //进行保存数据 save_cache.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String save_str = edit_cache.getText().toString().trim(); mAcache.put(CacheConsts.DEMO_CACHE_KEY, save_str); showToastMsgShort("缓存成功..."); } }); //进行查询数据 query_cache.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String query_str=mAcache.getAsString(CacheConsts.DEMO_CACHE_KEY); tv_cache.setText(query_str); } }); } ~~~ 运行结果如下:  ![](https://box.kancloud.cn/2016-01-18_569c8eb0b18d5.jpg)  到此为止我们今天ACache的讲解和使用结果,详细代码项目地址:  [https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)  同时欢迎大家star和fork整个开源快速开发框架项目~如果有什么意见和反馈,欢迎留言,必定第一时间回复。也欢迎有同样兴趣的童鞋加入到该项目中来,一起维护该项目。