一、缓存的作用

请求数据的时候,首先进行推断,能否够从缓存中获取数据,假设满足条件,则直接从缓存中获取数据。否则请求新的数据。这样比没有缓存的情况下。每次都要从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. sql is null

    select * from a or state is null)

  2. git-忽略文件改动不进行提交

    命令:git update-index --assume-unchanged 文件名 作用:忽略文件的改动,但是不加入.gitignore 文件中,这样可以达到仅在本地目录中忽略,不影响其他团队成员的 ...

  3. excel数据比对,查找差异

    1.选中需比对的数据 2.开始->条件格式->突出显示单元格规则->重复值 3.选择唯一值,点击确定 4.结果展示 5.颜色标识的即:不同值

  4. Java实现LRU(最近最少使用)缓存

    package com.jd.test; import java.io.Serializable; import java.util.LinkedHashMap; import java.util.c ...

  5. Java开发中常见的异常问题

    要调试程序,自然需要对程序中的常见的异常有一定的了解,因此在这里我将一些常见的Java程序中的异常列举出来给大家参考 AD: 作为一名开发者,Java程序员,很自然必须熟悉对程序的调试方法.而要调试程 ...

  6. 牛客OI赛制测试赛2(0906)

    牛客OI赛制测试赛2(0906) A :无序组数 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序意思就是(a,b)和(b,a) 算一组. 输入描述: ...

  7. 02-Mysql中的运算符

    Mysql中运算符 1.算术运算符运算符 作用+   加法-    减法*    乘法/,DIV     除法,返回商%,MOD       除法,返回余数 mysql root@localhost: ...

  8. 如何使用GoEasy实现PHP与Websocket实时通信

    最近搞了搞websocket 做了个简答的聊天demo 1.      从GoEasy获取appkey appkey是验证用户的有效性的唯一标识. Ø  注册账号. GoEasy官网:https:// ...

  9. markdown pad激活

    <iframe src="></iframe> ---恢复内容开始--- 注册码 Soar360@live.com GBPduHjWfJU1mZqcPM3BikjYK ...

  10. 05 selenium模块

    selenium模块 selenium selenium是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作. selenium最初是一个自动化测试工具,而爬虫中使 ...