以前做過數據緩存的項目,也就是實現離線操作。當時剛開始做項目,我們都沒什麼經驗,但是緩存數據無非是數據庫或者文件,但是我們選擇用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