Volley緩存機制

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會根據這個請求是否設置緩存進行緩存與否,將數據返回

發佈了44 篇原創文章 · 獲贊 23 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章