Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

数据请求优化之容器缓存

$
0
0

今天qiugong兄弟喜得贵子,升级当爸,开心之余,决定写篇博客庆祝下,之前忙着一些琐事,自从上篇博客最新Retrofit + RxJava + MVP 发表后,原本打算写上十篇左右贴子来讲述之前传到github上的framework,却拖了一个多月还未动笔,惭愧。

对于日常开发中,有时候很多接口并不需要多次调用,只需要访问一次就够,比如省、市、区三级目录,如果把这个放在本地,处理不当就会卡死,之前想用文本存储,文本中放json,三级目录的完整json还是挺大的,好像有140kb,具体记不清了,还有一种方案就是放xml,也还是觉得不妥,处理也很麻烦,比较好的方案,个人推荐使用容器缓存。

先上代码:

/**
 * 配置过期类型和时间
 *
 * Created by Zero on 2017/5/30.
 */

public class CacheObject {

    private long timestamp;
    private int period = -1;
    private Object data;

    /**
     * @param data
     * @param period -1 表示永不过期,大于0表示过期的时间,单位分钟
     */
    public CacheObject(Object data, int period) {
        timestamp = System.currentTimeMillis();
        this.data = data;
        this.period = period;
    }

    public Object getObject() {
        return data;
    }

    public boolean isValid() {
        if (period == -1 || System.currentTimeMillis() < (timestamp + period * 60000)) {
            return true;
        }
        return false;
    }

    public void setPeriod(int period) {
        this.period = period;
    }

    public int getPeriod() {
        return period;
    }
}

这里是对缓存类型和时间的配置,可以配置成永不过期,也可以配置成指定时间过期,比如有些token,在后台多少时间后便会过期,招商银行的APP就是这么做的,每次把app打入冷宫后,时间一长,矫情的她就离我而去,需要重新登录,对于省市区三级目录,这些属于常年不变的,可以使用长期缓存。

/**
 * 数据请求中对cache进行管理
 * Created by Zero on 2017/5/30.
 */

public class CacheManager {

    private static Map<String, CacheObject> cacheMap = new HashMap<>();

    /**
     * 添加到cache
     *
     * @param key
     * @param data
     * @param period
     */
    public static void addData(String key, Object data, int period) {
        CacheObject cacheObject = getData(key);
        if (cacheObject != null) {
            /**
             * 如果类型不同,便重新加入到缓存中
             */
            if (period != cacheObject.getPeriod()) {
                cacheObject.setPeriod(period);
                /**
                 * 移除老的value
                 */
                removeInvalidData(key);
                /**
                 * 重新putvalue
                 */
                cacheMap.put(key, cacheObject);
            }
        } else {
            cacheObject = new CacheObject(data, period);
            cacheMap.put(key, cacheObject);
        }
    }

    /**
     * 获取cache
     *
     * @param key
     * @return
     */
    public static CacheObject getData(String key) {
        CacheObject cacheObject = cacheMap.get(key);
        if (cacheObject != null) {
            /**
             * 判断缓存是否过期
             */
            if (cacheObject.isValid()) {
                return cacheObject;
            } else {
                removeInvalidData(key);
            }
        }
        return null;
    }

    /**
     * 移除过期的key
     *
     * @param key
     */
    public static void removeInvalidData(String key) {
        if (cacheMap.containsKey(key)) {
            cacheMap.remove(key);
        }
    }
}

此类主要用于缓存,把请求到的数据,以 Url 为唯一标识并作为 key 建立缓存,首先通过 key 获取缓存中是否存在缓存,如果没有,便去请求数据,把得到的结果缓存到容器中,如果之前已经建立过缓存,便直接从容器中读取缓存,减小服务器压力,在并发量大的时候,大大减小服务器压力。此处使用的是 map 缓存,采用 map ,主要原因是键值对可以更高效的为我们服务,key–>value。

addData方法,顾名思义,添加缓存,看下源码,并不是无脑的添加,还是先做判断是否有缓存,上述已经提到,如果没有缓存便会添加到容器中,如果有,便会判断缓存时间类型是否有改变,如果有没有改变,便不会添加到缓存中,如果有改变,便会先移除老的数据,把新数据加入进去。

项目已上传,戳此进入github。

作者:pangpang123654 发表于2017/7/17 18:09:41 原文链接
阅读:794 评论:5 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>