【FastDev4Android框架开发】Android 数据缓存器ACache的详解和使用(四)

来源:互联网 发布:有淘宝店铺可以直播吗 编辑:程序博客网 时间:2024/05/16 18:21

(一):写在前面的话
接着上一篇继续更新,上一篇文章已经把FastDev4Android项目列表下拉刷新组件(PullToRefreshListView)组件做了讲解和使用。今天项目更新是得数据缓存器(ACache)的详解和使用。
(二):功能介绍
2.1:基本介绍
ACache项目是我去年在Github上面发现的一个开源项目,首先感谢作者,感谢Github开源的力量。ACache是一个比较轻量级的数据缓存管理器(一个类ACache.java)解决问题,所以学习起来就非常简单,在中小型项目中可以较好的去使用。ACache使用采用手机包名路径下文件数据保存方式进行数据缓存,同时可以自定义设置数据缓存的路径,缓存的文件大小,以及缓存的文件数量以及相应的缓存过期时间。下面我们来看一下整个类中相应的方法和变量以及常量,这样对整个类有一个直观的了解。
这里写图片描述
这里写图片描述
查看以上各种方法,我们可以知道ACache给我们提供了文本数据,JSON格式数据,图片等信息缓存,当然我们也可以通过实际的项目情况,对该类进行其他格式数据的扩展。
2.2:ACache流程
ACache请求处理流程
这里写图片描述
(三):核心方法介绍
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);            }        });    }

运行结果如下:
这里写图片描述
到此为止我们今天ACache的讲解和使用结果,详细代码项目地址:
https://github.com/jiangqqlmj/FastDev4Android
同时欢迎大家star和fork整个开源快速开发框架项目~如果有什么意见和反馈,欢迎留言,必定第一时间回复。也欢迎有同样兴趣的童鞋加入到该项目中来,一起维护该项目。

5 0