### 导读
电商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操作,提高效率;