android app 缓存 ---- android 文件缓存使用流程解析

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33078541/article/details/50589144


在度娘那里搜索了一下,关于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);



备注:缓存的使用,要主要考虑全面,有网无网,有缓存无缓存,缓存是否过期,一点考虑不到就可能出现指向空路径,指向空文件,等等异常。


结束。


如有不明确的地方,可以回复,荣幸与各位开发者公共探讨。


原创文章,转载请注明出处:
http://blog.csdn.net/qq_33078541?viewmode=contents


展开阅读全文

没有更多推荐了,返回首页