【Android开发—电商系列】(三):缓存的使用

导读

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

文章导航