### 導讀
電商APP的首頁是商品展示頁面,在網絡連接不可用時,如果不使用緩存,數據獲取不到,那么首頁就空白一片,這樣用戶體驗很不好,所以這個時候我們要用到緩存。
### 思路
在有網的時候把數據存到緩存中,沒網的時候數據從緩存中獲得。
### 代碼實現
~~~
public class AppContext extends Application {
/**
* 獲得首頁分類商品列表
* @return
* @throws AppException
*/
public HomePagesVo getHomePages() throws AppException {
HomePagesVo homePagesVo = null;
// 構建緩存文件的key
String key = "homePagesVo_1" ;
// 1.如果聯網則首先從服務器獲取數據
if (isNetworkConnected()) {
try {
//從服務器獲取channelCategoryVo的集合
homePagesVo = ApiClient.GetHomePages(this);
// 如果能夠獲取到服務器中的數據則保存到本地緩存,只有保證數據不為空,且獲取到的結果為true的時候才緩存到本地
if (homePagesVo != null
&& homePagesVo.getResult().equals("true")) {
homePagesVo.setCacheKey(key);
saveObject(homePagesVo, key);
}else{
homePagesVo=null;
}
} catch (AppException e) {
// 如果出現訪問中途斷網,則獲取本地緩存中的數據
homePagesVo = (HomePagesVo)readObject(key);
}
}
// 2.如果未聯網則從緩存中獲取數據
else {
homePagesVo = (HomePagesVo) readObject(key);
}
return homePagesVo;
}
/**
* 保存對象
* @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;
}
/**
* 檢測網絡是否可用
*
* @return
*/
public boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return ni != null && ni.isConnectedOrConnecting();
}
}
~~~
待優化之處
在保存對象時應判斷一下緩存是否存在,而且增加一個布爾類型參數表示用戶是否要刷新數據。
如果用戶沒有刷新數據,且緩存已經存在,就不要再次保存對象(SaveObject),要盡量減少IO操作,提高效率;