在度娘那里搜索了一下,关于android 缓存的资源介绍,发现都是泛泛而谈,没有给出详细的使用方法。看各路大神的介绍,缓存一般分为两种形式(1.数据库缓存,2.文件缓存)。
数据库缓存,看到这个名字,想必都知道怎么回事了,将网络请求的数据,一一对应存入本地数据库中,来达到缓存的效果。
文件缓存,这里主要是txt文件缓存,将网络请求的数据缓存到本地文件中,来达到缓存效果。
为什么要用缓存,这里就不说了,百度讲的最清楚的就属这个了。总而言之为了更好的用户体验(没网络的时候也有缓存数据,不用不停的去请求数据减轻服务器压力,减少请求数据的耗时卡顿,等等等等)
文件缓存的原理:
从最外层的有无网络开始说起,当无网络的时候,进入缓存的判断,判断缓存文件是否存在,存在直接加载缓存,不存在,给个无网络操作。
在有网络的时候,先进行缓存判断,看文件缓存最后编辑时间到现在的时间段,是否超过了自己在程序中设定的缓存时间,如果超出了缓存时间,请求网络数据,更新覆盖原缓存,如果没有超出缓存时间,直接加载缓存数据,不做网络请求。
原理就是这样。下面上代码,走一遍缓存流程。
/** * Created by GT on 2015/10/21. * 文件缓存工具类 */ public class FileUtil { public static int CACHE_TIME = 10000 * 6;//1分钟 public static int CACHE_TIME1 = 10000 * 6 * 60 * 2;//2个小时 public static int CACHE_TIME2 = 10000 * 6 * 60 * 3;//3个小时 public static int CACHE_TIME3 = 10000 * 6 * 60 * 5;//5个小时 public static int CACHE_TIME4 = 10000 * 6 * 60 * 7;//7个小时 public static int CACHE_TIME5 = 10000 * 6 * 60 * 12;//12个小时 public static int CACHE_TIME6 = 10000 * 6 * 60 * 24;//24个小时 public static String CACHEFILEPATH = Tools.getSDPath() + "/pdsrd"; public static String SHANGCHENGHUANDENG = "shangchenghuandeng.txt";//商城幻灯片 /** * 将数据写入文件缓存 * * @param ser * @param file * @return */ public static boolean saveObject(Serializable ser, File file) { File newFile = new File(CACHEFILEPATH); if (!newFile.exists()) { newFile.mkdirs(); } FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream(file, false); oos = new ObjectOutputStream(fos); oos.writeObject(ser);// 写入 return true; } catch (Exception e) { e.printStackTrace(); return false; } finally { try { fos.close(); oos.close(); } catch (Exception e) { } } } /** * 读取对象 * * @param file * @return */ public static Serializable readObject(File file) { FileInputStream fis = null; ObjectInputStream ois = null; try { fis = new FileInputStream(file); //获得输入流 ois = new ObjectInputStream(fis); return (Serializable) ois.readObject(); } catch (StreamCorruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); return null; } finally { try { ois.close(); } catch (Exception e) { } try { fis.close(); } catch (Exception e) { } } return null; } /** * 判断文件缓存是否过期 * * @param data * @param time * @return */ public static boolean isCacheDataFailure(File data, int time) { boolean failure = false; if ((System.currentTimeMillis() - data.lastModified()) > time) failure = true; else if (!data.exists()) failure = true; return failure; } public static String getCacheDecodeString(String url) { //1. 处理特殊字符 //2. 去除后缀名带来的文件浏览器的视图凌乱(特别是图片更需要如此类似处理,否则有的手机打开图库,全是我们的缓存图片) if (url != null) { return url.replaceAll("[.:/,%?&=]", "+").replaceAll("[+]+", "+"); } return null; } }
这个是缓存工具类,重要的两个,数据的写入和读取。 上面的缓存时间,由自己决定,如果接口数据更新比较快,则设定短时间更新,如该数据变动不频繁,可适量的加长缓存时间,减少网络请求。
if (Tools.getMobilNetStatus(this) == 0) {//判断是否有网络,这里是没有网络 if (!new File(topPicFilePath).exists()) {//判断缓存文件是否存在,如果不存在给个提示 Toast.makeText(ShangchengActivity.this, "当前网络不可用", Toast.LENGTH_SHORT).show(); } else { //这里是缓存文件存在的情况,存在缓存文件,因为无网,不判断缓存是否过期,直接拿出缓存.拿出缓存,直接绑定控件即可 File slideFile = new File(FileUtil.CACHEFILEPATH, FileUtil.SHANGCHENGHUANDENG); slideBeans = (ArrayList<ShouYeAdBean>) FileUtil.readObject(slideFile); setSlideImg(slideBeans);}
else {//如果有网络 /** * 检查缓存是否过期 */ String topPicFilePath = FileUtil.CACHEFILEPATH + "/" + FileUtil.SHANGCHENGHUANDENG;//缓存地址 if (new File(topPicFilePath).exists()) { //先检查缓存文件是否存在 if (FileUtil.isCacheDataFailure(new File(topPicFilePath), FileUtil.CACHE_TIME1)) { //判断文件缓存是否过期,第一个参数为文件,第二个参数为缓存时间。判断为过期,则执行下一步 requestSlide();//重新请求数据 } else {//判断缓存没有过期,读取缓存,加载缓存到控件,避免网络请求数据 File file = new File(FileUtil.CACHEFILEPATH, FileUtil.SHANGCHENGHUANDENG); slideBeans = (ArrayList<ShouYeAdBean>) FileUtil.readObject(file); setSlideImg(slideBeans); } } else {//这里判断缓存文件不存在的情况下,重新请求一下 requestSlide();//加载幻灯片 }
以上就是进入当前界面的判断和读取缓存的思路和程序实现。
上面只提到了读缓存,存缓存放在什么地方呢,当然是放在每次的网络请求中,请求成功了,就增加或者更新缓存。
File file = new File(FileUtil.CACHEFILEPATH, FileUtil.SHANGCHENGHUANDENG); FileUtil.saveObject(slideBeans, file);
备注:缓存的使用,要主要考虑全面,有网无网,有缓存无缓存,缓存是否过期,一点考虑不到就可能出现指向空路径,指向空文件,等等异常。