10分钟教你学会三级缓存

一、开篇序言

网上很多图片三级缓存的文章,这里讲的是Json缓存,这类文章网上缺乏,有必要分享分享。

二、先上图,看效果



二、分析LruCache如何缓存数据

上图是完整的三级缓存的Demo,内存缓存使用LruCache,SD卡缓存使用数据库(当然你缓存到文件也可以)。

LruCache既然可以缓存到内存?没错,LruCache不只是可以缓存图片,还可以缓存数据到内存。

LruCache这个类不是第三方提供的,android API自带,建议使用v4包里面的(android.support.v4.util.LruCache)

使用LruCache存储数据

        int maxSize = 10;//缓存最大值:10byte(字节),UTF-8中,每个英文字母占一个byte
        LruCache<String, String> lruCache = new LruCache<String, String>(maxSize) {
            /**计算大小*/
            @Override
            protected int sizeOf(String key, String value) {
                return value.getBytes().length;//字符串长度
            }
        };
        lruCache.put("1", "AAA");
        lruCache.put("2", "BBB");
        lruCache.put("3", "CCC");
        print(lruCache);//print方法在下面
        lruCache.put("4", "DDD");
        print(lruCache);
        String value = lruCache.get("3");//key位3的value是CCC
        print(lruCache);

打印结果(附上分析)

<pre name="code" class="java">------------------start------------------  
key=1,value=AAA  
key=2,value=BBB  
key=3,value=CCC  
-------------------end-----------------  
------------------start------------------  
key=2,value=BBB  
key=3,value=CCC  
key=4,value=DDD   //分析:put("DDD")后,存储空间变成12byte,超出我们设置最大值10byte,所有删除最近最少使用的"AAA"  
-------------------end-----------------  
------------------start------------------  
key=2,value=BBB  
key=4,value=DDD  
key=3,value=CCC  //分析:CCC顺序和之前不一样,因为上面第15行代码访问了CCC,LruCache内部维护LinkHashMap集合,会对集合进行LRU算法排序。  
-------------------end-----------------  

 

print方法:

   /**打印集合 */
    private void print(LruCache<String, String> lruCache) {
        LogUtil.d("------------------start------------------");
        Map<String, String> snapshot = lruCache.snapshot();
        for (Map.Entry<String, String> entry : snapshot.entrySet()) {
            LogUtil.d("key=" + entry.getKey() + ",value=" + entry.getValue());
        }
        LogUtil.d("-------------------end-----------------");
    }
综上所述:

1.LruCache可以缓存数据,不只是缓存图片,而且LruCache内部维护了Map集合,所有我们的数据其实是缓存到了内存中

2.LruCache内部使用LRU算法对数据排序

上面的分析是为了下面Demo做知识储备,学会了这个内容,下面正式进入到项目中


三、结合LruCache处理三级缓存

3.1网络层

这里使用谷歌的Volley请求网络,每次获取网络数据并存储到内存中。LruCache的key是页码,value是每页数据
 /**从网络获取数据*/
    private void getDataFromInternet(String reqFlag, RequestQueue queue, final int pagenum, final Response.Listener<String> listener, Response.ErrorListener errListener) {
        StringRequest request = new StringRequest(url + "?pagenum=" + pagenum, new Response.Listener<String>() {
            @Override
            public void onResponse(String data) {
                listener.onResponse(data);//返回给Activity
                //拿到数据,缓存到内存
                storeToMemory(pagenum, data);
                showToast("从网络获取第" + pagenum + "页数据");
            }
        }, errListener);
        request.setTag(reqFlag);
        queue.add(request);//发起网络请求
    }

3.2内存层

内存使用了LruCache,内存层主要工作:将网络数据存储到内存,从内存中获取数据,如下:

1.判断内存有没有数据

   private boolean exitInMemory(int pagenum){
        if(lruCache == null) return false;
        String data = lruCache.get(pagenum + "");
        return !TextUtils.isEmpty(data);
    }

2.获取内存数据

    public String getDataFromMemory(int pagenum){
        return lruCache.get(pagenum + "");
    }

3.将网络数据存储到内存

   /**将数据存储到内存*/
    public void storeToMemory(int pagenum, String data){
        //lrucache设置最大值:MEMORY_MAX_SIZE=4000(byte)
        if(lruCache == null) lruCache = new LruCache<String, String>(MEMORY_MAX_SIZE){
            @Override
            protected int sizeOf(String key, String value) {
                return value.getBytes().length;//计算每次存入内容大小
            }
        };
        //存储到内存
        lruCache.put(pagenum + "", data);//key是页码,每一页数据是value
        LogUtil.d("内存数据大小=" + lruCache.size());//test
        print();//test
    }

3.3网络结合内存提高用户体验

	/**获取酒店列表数据*/
    public void getHotelList(String reqFlag, RequestQueue queue, final int pagenum, final Response.Listener<String> listener, Response.ErrorListener errListener){
        if(exitInMemory(pagenum)){//如果内存中存在,直接返回内存数据
            String data = getDataFromMemory(pagenum);
            listener.onResponse(data);//回调给UI
        }else {//从网络获取数据
            getDataFromInternet(reqFlag, queue, pagenum, listener, errListener);
        }
    }

3.4最后一层:SD卡

为了篇幅言简意赅,这里不再分析如何缓存Json到SD卡。给大家提供参考思路,或者直接下载完整Demo参考。
思路:高德地图使用了DiskLruCache将数据缓冲到SD卡,不使用LruCache算法缓存到文件或者数据库都没问题,看需求。内存中使用了LruCache,所以SD卡可以不使用LRU。


四、Demo下载地址

依赖的服务器代码:https://github.com/jiyouliang/VolleyTest









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值