以前做过数据缓存的项目,也就是实现离线操作。当时刚开始做项目,我们都没什么经验,但是缓存数据无非是数据库或者文件,但是我们选择用xml文件来存储数据,现在看来是有点走远路了,oschina-app通过实现对object的实体流读写来完成数据缓存,来看下显现流程。
1,首先在ui线程中另起线程,获取数据:
/**
* 线程加载帖子数据
*
* @param catalog
* 分类
* @param pageIndex
* 当前页数
* @param handler
* 处理器
* @param action
* 动作标识
*/
private void loadLvQuestionData(final int catalog, final int pageIndex,
final Handler handler, final int action) {
mHeadProgress.setVisibility(ProgressBar.VISIBLE);
new Thread() {
public void run() {
Message msg = new Message();
boolean isRefresh = false;
if (action == UIHelper.LISTVIEW_ACTION_REFRESH
|| action == UIHelper.LISTVIEW_ACTION_SCROLL)
isRefresh = true;
try {
PostList list = appContext.getPostList(catalog, pageIndex,
isRefresh);
msg.what = list.getPageSize();
msg.obj = list;
} catch (AppException e) {
e.printStackTrace();
msg.what = -1;
msg.obj = e;
}
msg.arg1 = action;
msg.arg2 = UIHelper.LISTVIEW_DATATYPE_POST;
if (curQuestionCatalog == catalog)
handler.sendMessage(msg);
}
}.start();
}
在AppContext中判断是从本地缓存取还是从网络获取:
/**
* 帖子列表
* @param catalog
* @param pageIndex
* @return
* @throws ApiException
*/
public PostList getPostList(int catalog, int pageIndex, boolean isRefresh) throws AppException {
PostList list = null;
String key = "postlist_"+catalog+"_"+pageIndex+"_"+PAGE_SIZE;
if(isNetworkConnected() && (!isReadDataCache(key) || isRefresh)) {
try{
list = ApiClient.getPostList(this, catalog, pageIndex, PAGE_SIZE);
if(list != null && pageIndex == 0){
Notice notice = list.getNotice();
list.setNotice(null);
list.setCacheKey(key);
saveObject(list, key);
list.setNotice(notice);
}
}catch(AppException e){
list = (PostList)readObject(key);
if(list == null)
throw e;
}
} else {
list = (PostList)readObject(key);
if(list == null)
list = new PostList();
}
return list;
}
根据程序判断,如果是本地没有走网络获取,并缓存到本地saveObject(list, key);,有则直接读取list = (PostList)readObject(key);直接看上数据缓存和读取的代码:
/**
* 保存对象
* @param ser
* @param file
* @throws IOException
*/
public boolean saveObject(Serializable ser, String file) {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try{
fos = openFileOutput(file, MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(ser);
oos.flush();
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}finally{
try {
oos.close();
} catch (Exception e) {}
try {
fos.close();
} catch (Exception e) {}
}
}
/**
* 读取对象
* @param file
* @return
* @throws IOException
*/
public Serializable readObject(String file){
if(!isExistDataCache(file))
return null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try{
fis = openFileInput(file);
ois = new ObjectInputStream(fis);
return (Serializable)ois.readObject();
}catch(FileNotFoundException e){
}catch(Exception e){
e.printStackTrace();
//反序列化失败 - 删除缓存文件
if(e instanceof InvalidClassException){
File data = getFileStreamPath(file);
data.delete();
}
}finally{
try {
ois.close();
} catch (Exception e) {}
try {
fis.close();
} catch (Exception e) {}
}
return null;
}
现在看来确实很简单,只要在请求前读数据在请求后写数据就行了。
网络获取部分就不说,没什么特殊的就是HttpClient,别忘了出来各种异常就行了。
oschina-app完整源码下载:http://download.csdn.net/detail/xiangxue336/7023661