关闭

Volley缓存机制

标签: Volley缓存机制LruCache二级缓存ImageLoade
833人阅读 评论(2) 收藏 举报
分类:

Volley简介

    Volley是Goole在2013年Google I/O大会上推出了一个新的网络通信框架,它是开源的。从名字由来和配图中无数急促的火箭可以看出 Volley 的特点:特别适合数据量小,通信频繁的网络操作。

    Volley加载JsonObjectRequest数据、StringRequest数据、ImageRequest图片数据仅仅实现了两级缓存(网络缓存、文件缓存),没有实现内存的缓存。Volley已经把各种异步任务、图片采样都封装好了。

    内存缓存使用lrucache类实现,需要我们手动添加进去。没有使用软引用缓存。因为4.0之后的android系统已经不推荐使用软引用缓存了。

Volley请求数据原理图
这里写图片描述

这里写图片描述

Volley缓存机制

    volley发起一个请求先从缓存中去查找,如果缓存有数据,直接返回结果,如果没有缓存中没有数据,volley会发起网络请求,此时展示数据,同时将网络获取的数据保存到缓存中。
    那咱们看一下缓存数据在哪里:想要使用Volley请求数据,必须要获取RequestQueue这个对象,Volley提供了公共静态的方法:newRequestQueue(Context context)
public static RequestQueue newRequestQueue(Context context) {
        return newRequestQueue(context, null);
    }

该方法中返回了:return newRequestQueue(context, null); 接续跟着代码走

public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();

        return queue;
    }
    此时我们发现,缓存的地址: File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);也就是默认的缓存地址是程序安装包下的data/data/中,接下来看一下RequestQueue的构造方法说明,继续看源码
/**
     * Creates the worker pool. Processing will not begin until {@link #start()} is called.
     *
     * @param cache A Cache to use for persisting responses to disk
     * @param network A Network interface for performing HTTP requests
     */
    public RequestQueue(Cache cache, Network network) {
        this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
    }

从源码注释中cache A Cache to use for persisting responses to disk我们知道缓存其实是放到SD卡中了,并没有实现内存缓存即并没有实现LruCache

Volley内存缓存

    只有加载图片的时候才会有内存缓存,对于字符串一般都是文件缓存。我们学习一下ImageLoader,内存缓存的实现
    ImageLoader构造方法:
/**
     * Constructs a new ImageLoader.
     * @param queue The RequestQueue to use for making image requests.
     * @param imageCache The cache to use as an L1 cache.
     */
    public ImageLoader(RequestQueue queue, ImageCache imageCache) {
        mRequestQueue = queue;
        mCache = imageCache;
    }
    参数一是RequestQueue,其中可以指定文件缓存地址,我们通过单例模式创建RequestQueue这个类,就可以将文件缓存路径指定到SD卡上
    参数二是内存缓存,这个类是接口需要实现其中方法
/**
     * Simple cache adapter interface. If provided to the ImageLoader, it
     * will be used as an L1 cache before dispatch to Volley. Implementations
     * must not block. Implementation with an LruCache is recommended.
     */
    public interface ImageCache {
        public Bitmap getBitmap(String url);
        public void putBitmap(String url, Bitmap bitmap);
    }

给大家一个实例代码:

ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
//            内存缓存
            int maxSize = (int) (Runtime.getRuntime().totalMemory()/8);

            LruCache<String,Bitmap> mLruCache = new LruCache<String,Bitmap>(maxSize){

//              告诉LruCache存入的数据多大
                @Override
                protected int sizeOf(String key, Bitmap value) {
//                    存入每张图片的大小
                    return value.getRowBytes()*value.getHeight();
                }
            };

//            缓存中获取数据
            @Override
            public Bitmap getBitmap(String url) {
                return mLruCache.get(url);
            }

//            第一次使用,肯定没有数据,联网请求,将数据存起来,方便以后使用
            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                mLruCache.put(url,bitmap);
            }
        };

对于请求图片的ImageLoader,这个类请求图片的机制是这样的,就是一个经典的三级缓存了:
1、当ImageLoader发起图片请求时,先从内存缓存LruCache中根据key(即请求url)获取缓存数据,如果有数据,直接返回数据,不进行其他操作了

2、如果内存缓存中没有数据,ImageLoader中第一参数requestQueue就会先从文件缓存中查找是否存在数据,如果有数据,直接返回数据,不进行联网操作了

3、如果文件缓存中么有数据,那就只能进行联网操作,联网操作获取数据, Volley会根据这个请求是否设置缓存进行缓存与否,将数据返回

3
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:38791次
    • 积分:801
    • 等级:
    • 排名:千里之外
    • 原创:39篇
    • 转载:3篇
    • 译文:0篇
    • 评论:13条
    最新评论