oschina-app 源码分析-数据缓存(离线功能)

来源:互联网 发布:sql身份证取年龄 编辑:程序博客网 时间:2024/05/05 04:41

         以前做过数据缓存的项目,也就是实现离线操作。当时刚开始做项目,我们都没什么经验,但是缓存数据无非是数据库或者文件,但是我们选择用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

0 0