一、缓存的作用

请求数据的时候,首先进行推断,能否够从缓存中获取数据,假设满足条件,则直接从缓存中获取数据。否则请求新的数据。这样比没有缓存的情况下。每次都要从server请求数据要快,并且。没有网的情况下。也能够浏览已经缓存了的数据,极大的提高了用户的体验。

二、源代码解析

源代码中用到缓存的地方有:

1 请求数据之前。先推断能否够从缓存中获取,假设满足条件,则直接从缓存中读取。否则,向server请求新的数据。

// 获取缓存的文件夹
private String getCacheKey() {
return new StringBuilder(getCacheKeyPrefix()).append("_")
.append(mCurrentPage).toString();
} // 请求数据,推断能否够从缓存中获取数据
protected void requestData(boolean refresh) {
String key = getCacheKey();
if (isReadCacheData(refresh)) {
readCacheData(key);
} else {
// 取新的数据
sendRequestData();
}
} //推断是否须要读缓存数据
protected boolean isReadCacheData(boolean refresh) {
String key = getCacheKey();
if (!TDevice.hasInternet()) {
return true;
}
// 第一页若不是主动刷新,且缓存存在,优先取缓存的
if (CacheManager.isExistDataCache(getActivity(), key) && !refresh
&& mCurrentPage == 0) {
return true;
}
// 其它页数的,缓存存在以及还没有失效,优先取缓存的
if (CacheManager.isExistDataCache(getActivity(), key)
&& !CacheManager.isCacheDataFailure(getActivity(), key)
&& mCurrentPage != 0) {
return true;
} return false;
}

2 对从server中获取的最新数据进行保存到缓存的操作

private class SaveCacheTask extends AsyncTask<Void, Void, Void> {
private final WeakReference<Context> mContext;
private final Serializable seri;
private final String key; private SaveCacheTask(Context context, Serializable seri, String key) {
mContext = new WeakReference<Context>(context);
this.seri = seri;
this.key = key;
} @Override
protected Void doInBackground(Void... params) {
CacheManager.saveObject(mContext.get(), seri, key);
return null;
}
}

当中saveObject方法实现例如以下

public static boolean saveObject(Context context, Serializable ser, String file) {

    FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = context.openFileOutput(file, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(ser);
oos.flush();
return true;

要注意的是

(1) data是ListEntity接口的对象,该接口继承了Serializable接口,所以能够直接传參。

(2) key 在这里作为文件路径(缓存文件夹)。

3 最后,值得一提的是(尽管和Cache没有太大关系),解析完返回的数据后。刷新界面时,对返回数据的处理

 protected void executeOnLoadDataSuccess(List<T> data) {
...
//对server返回来的数据和已有的数据进行对照。
//假设同样。则将同样的item删掉。 最后看data集合的大小
//假设data最后仍然有item ,则更新ListView for (int i = 0; i < data.size(); i++) {
if (compareTo(mAdapter.getData(), data.get(i))) {
data.remove(i);
i--;
}
}
int adapterState = ListBaseAdapter.STATE_EMPTY_ITEM;
if ((mAdapter.getCount() + data.size()) == 0) {
adapterState = ListBaseAdapter.STATE_EMPTY_ITEM;
} else if (data.size() == 0
|| (data.size() < getPageSize() && mCurrentPage == 0)) {
adapterState = ListBaseAdapter.STATE_NO_MORE;
mAdapter.notifyDataSetChanged();
} else {
adapterState = ListBaseAdapter.STATE_LOAD_MORE;
}
mAdapter.setState(adapterState);
mAdapter.addData(data);
// 推断等于1是由于最后有一项是listview的状态??
if (mAdapter.getCount() == 1) { if (needShowEmptyNoData()) {
mErrorLayout.setErrorType(EmptyLayout.NODATA);
} else {
mAdapter.setState(ListBaseAdapter.STATE_EMPTY_ITEM);
mAdapter.notifyDataSetChanged();
}
}
}

总结:

1 以上是自己初步从源代码中总结出来的一点关于缓存设计的认识和理解。肯定会有非常多不周或者不准确的地方,希望能够得到广大博友的指点。自己也会尽量抽出时间完好的。

2 源代码中有些地方,现阶段我也没有全然看懂。但仅仅要不影响大体上的把握,还是能够将自己的理解和整理的东西先分享出来。

作者:项昂之

时间:2015.7.15

OSChinaclient源代码学习(2)--缓存的设计的更多相关文章

  1. OSChinaclient源代码学习(1)--Android与Server的交互

    这里主要针对"综合"这个选项卡下的"资讯"模块为样例.对核心代码进行解读. 准备工作:參考我的另外一篇博客 http://blog.csdn.net/csp27 ...

  2. OSChinaclient源代码学习(3)--轮询机制的实现

    主要以OSChina Androidclient源代码中Notice的轮询机制进行解读. 一.基础知识 一般IM(即使通讯)的实现有两种方式:推送和轮询,推送就是server主动向client发送消息 ...

  3. jQuery源代码学习_工具函数_type

    jquery源代码学习_工具函数_type jquery里面有一个很重要的工具函数,$.type函数用来判断类型,今天写这篇文章,是来回顾type函数的设计思想,深入理解. 首先来看一下最终结果: 上 ...

  4. [Java] LinkedList / Queue - 源代码学习笔记

    简单地画了下 LinkedList 的继承关系,如下图.只是画了关注的部分,并不是完整的关系图.本博文涉及的是 Queue, Deque, LinkedList 的源代码阅读笔记.关于 List 接口 ...

  5. 开源中国安卓client源代码学习(一) 渐变启动界面

    开源中国安卓client源代码学习(一) 渐变启动界面 准备学习安卓开发, 看到网上有人推荐开源中国安卓client的源代码, 说里面包括了大部分技术, 于是准备好好研究研究. 特开通此系列博客来记录 ...

  6. jQuery源代码学习笔记_工具函数_noop/error/now/trim

    jQuery源代码学习笔记_工具函数_noop/error/now/trim jquery提供了一系列的工具函数,用于支持其运行,今天主要分析noop/error/now/trim这4个函数: 1.n ...

  7. .NET 缓存模块设计

    上一篇谈了我对缓存的概念,框架上的理解和看法,这篇承接上篇讲讲我自己的缓存模块设计实践. 基本的缓存模块设计 最基础的缓存模块一定有一个统一的CacheHelper,如下: public interf ...

  8. 12个学习 CSS3 网站布局设计的优秀案例

    网络上有很多的 CSS 画廊站点供大家对各类网站作品进行打分和评论,每天有数以百计的优秀网站被推荐上面,这对于网页设计师来说是很好的灵感来源.今天,我们选择了15赢得 CSS 设计大奖的优秀作品,帮助 ...

  9. IOS编程 图片缓存模块设计

    手机客户端为什么会留存下来?而不是被一味的Wap替代掉?因为手机客户端有Wap无可替代的优势,就是自身较强的计算能力. 手机中不可避免的一环:图片缓存,在软件的整个运行过程中显得尤为重要. 先简单说一 ...

随机推荐

  1. centos7下LVM挂载和扩容

    说明:此操作在centos7下进行,如果是centos6发行版,需要注意格式化LV的文件系统类型(centos7.0开始默认文件系统是xfs,centos6是ext4).最后一步写入系统的类型,其中文 ...

  2. RTP/RTCP协议详解

    1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详细介绍IP协议族中用于实时语音.视频数据传输的标准协议RTP( Real-time Transp ...

  3. js 上传头像img

    <label> <div class="myusercenter-image-none"> <img src="" class=& ...

  4. int (*a)[10]和int *a[10]的区别

    有点晚了,放个链接,睡觉. https://stackoverflow.com/questions/13910749/difference-between-ptr10-and-ptr10

  5. mysql查询表中最小可用id值

    今天在看实验室的项目时,碰到的一个问题,.先把sql语句扔出来 // 这条语句在id没有1时,不能得到正确的查询结果. select min(id+1) from oslist c where not ...

  6. POI导出,开发中经常会遇到数据导出这样的问题,下面是我在开发中采用的解决方法,大家可以参考,具体的实现害的结合你自身的业务逻辑

    @RequestMapping(value = "/drawPayFailExport",method = RequestMethod.GET,produces = "a ...

  7. 企业级监控nagios实践

    nagios 监控服务应用指南 小区:视频监控,保安 企业工作中为什么要部署监控系统 监控系统相当于哨兵的作用,监控几百台上千台服务器,监控系统非常重要. 监控系统都需要监控 1. 本地资源:负载up ...

  8. c++_凑算式(最新方法)

    凑算式 B DEFA + --- + ------- = 10 C GHI (如果显示有问题,可以参见[图1.jpg]) 这个算式中A~I代表1~9的数字,不同的字母代表不同的数字. 比如:6+8/3 ...

  9. qt5.5.1配置winpcap4.1.2

    下载winpcap开发包,下载地址是http://www.winpcap.org/devel.htm 下载之后解压

  10. python re 正则表达式

    元字符和其含义 . 匹配除换行符以外的任意字符 \ 转义字符,使后一个字符改变原来的意思 \w 匹配字母.数字.下划线:[A-Za-z0-9_] \W 匹配特殊字符:[^A-Za-z0-9_] \s ...