volley全然解析

1、volley是什麼?

一、簡單介紹

  Volley是Goole在2013年Google I/O大會上推出了一個新的網絡通訊框架,它是開源的。從名字由來和配圖中無數急促的火箭可以看出 Volley 的特色:特別適合數據量小。通訊頻繁的網絡操做。(我的以爲 Android 應用中絕大多數的網絡操做都屬於這樣的類型)。java

  Volley載入圖片實現了兩級緩存(網絡緩存、文件緩存)。沒有實現內存的緩存。Volley已經把各類異步任務、圖片採樣都封裝好了。內存緩存使用lrucache類實現。需要咱們手動增長進去。android

沒有使用軟引用緩存。因爲4.0以後的android系統已經不推薦使用軟引用緩存了。算法

二、volley的總體設計

這裏寫圖片描寫敘述

這裏寫圖片描寫敘述

三、volley可以作什麼

JSON,圖像等的異步下載;
處理get、post等網絡請求;
網絡請求的排序(scheduling);
網絡請求的優先級處理;
緩存;
多級別取消請求;
和Activity和生命週期的聯動(Activity結束時同一時候取消所有網絡請求);
等等。緩存

它的設計目標就是很適合去進行數據量不大,但通訊頻繁的網絡操做,而對於大數據量的網絡操做。比方說下載文件等,Volley的表現就會很糟糕。markdown

2、圖片的三級緩存在volley中的實現

  事實上volley可以全然代替咱們手寫的三級緩存,因爲google已經對volley進行了很好的封裝,詳細說明例如如下:網絡

一、volley的推薦使用方法-單例模式

  使用volley時,咱們推薦把volley的使用封裝成單例使用。在application中初始化它。詳細代碼例如如下:app

單例:框架

package com.ht.xiangqu.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

/** * Created by annuo on 2015/6/16. */
public class RequestManager {
    private static RequestManager ourInstance;
    private RequestQueue requestQueue;
    private ImageLoader imageLoader;


    public static RequestManager createInstance(Context context) {
        if (context != null) {
            if (ourInstance == null) {
                ourInstance = new RequestManager(context);
            } else {
                throw new IllegalArgumentException("Context must be set");
            }
        }
        return ourInstance;
    }

    public static RequestManager getInstance() {
        return ourInstance;
    }

    private RequestManager(Context context) {
        requestQueue = Volley.newRequestQueue(context);
        imageLoader = new ImageLoader(
                requestQueue,
                new ImageLoader.ImageCache() {
                    private LruCache<String, Bitmap> cache
                            = new LruCache<>(20);
                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }

                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                }
        );
    }

    public RequestQueue getRequestQueue() {
        return requestQueue;
    }


    public ImageLoader getImageLoader() {
        return imageLoader;
    }

}

application:異步

package com.ht.xiangqu.util;

import android.app.Application;
import android.util.Log;

/** * Created by annuo on 2015/6/16. */
public class MainApplation extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        RequestManager.createInstance(getApplicationContext());
        Log.d("nihao", "nihao");
    }
}

二、內存緩存

  僅僅有載入圖片的時候纔會有內存緩存,對於字符串通常都是以後文件緩存。ide

  google並無本身主動的幫咱們實現內存的緩存,需要咱們本身手動增長進去。內存緩存在單例類中已經體現了(即LruCache),之後咱們每次使用的時候都沒必要再增長內存緩存。LruCache這個類是Android3.1版本號中提供的。假設你是在更早的Android版本號中開發,則需要導入android-support-v4的jar包。

三、文件緩存

  volley已經默認幫咱們實現了文件的緩存。

咱們經過源碼看一下:

/** * 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;
    }

  以上代碼是imageloader中的一段代碼,從中咱們可以看到在構造imageloader時,咱們已經默認的創建了一個L1級的緩存(文件緩存)。

那volley緩存下來的文件究竟在哪呢?見下圖:

這裏寫圖片描寫敘述

  詳細的位置就在如圖所看到的的位置。即data/data/應用程序的包名/volley。假設沒有改動volley的緩存位置。默認名字叫volley。

四、圖片的二次採樣的問題

  事實上volley默認的已經幫咱們作了圖片的二次採樣,僅僅是需要咱們在進行請求的時候,多增長兩個參數。咱們通常都忽略了這個問題,最後致使的是不斷的OOM。

/** * 這是訪問網絡圖片的核心方法 * @param requestUrl * @param imageListener * @param maxWidth * @param maxHeight * @return */
    public ImageContainer get(String requestUrl, ImageListener imageListener,
            int maxWidth, int maxHeight) {

Request<?

> newRequest = new ImageRequest(requestUrl, new Listener<Bitmap>() { @Override public void onResponse(Bitmap response) { onGetImageSuccess(cacheKey, response); } }, maxWidth, maxHeight, Config.RGB_565, new ErrorListener() { @Override public void onErrorResponse(VolleyError error) { onGetImageError(cacheKey, error); } }); mRequestQueue.add(newRequest); mInFlightRequests.put(cacheKey, new BatchedImageRequest(newRequest, imageContainer)); return imageContainer; }

  以上代碼是imageloader的核心方法,當中有兩個參數是maxWidth,maxHeight。咱們通常都忽略了這兩個參數。默認值是0和0,這樣二次採樣算法就不起做用了。咱們獲得的圖片是從server1:1哪來的。但是通常咱們設置了這兩個參數。就可以獲得咱們但願的縮小比例的圖片。這樣就可以全然的避免OOM。

3、volley的其它問題

一、圓角圖片的問題

public static ImageListener getImageListener(final ImageView view,
            final int defaultImageResId, final int errorImageResId) {
        return new ImageListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (errorImageResId != 0) {
                    view.setImageResource(errorImageResId);
                }
            }

            @Override
            public void onResponse(ImageContainer response, boolean isImmediate) {
                if (response.getBitmap() != null) {
                    //在這裏可以設置,假設想獲得圓角圖片的畫,可以對bitmap進行加工,可以給imageview加一個
                    //額外的參數
                    view.setImageBitmap(response.getBitmap());
                } else if (defaultImageResId != 0) {
                    view.setImageResource(defaultImageResId);
                }
            }
        };
    }

二、listview複用時,解決圖片錯位的問題

/** * 使用此方法可以解決圖片錯亂問題 * @param view * @param defaultImageResId * @param errorImageResId * @param url * @return */
    public static ImageListener getImageListener(
            final ImageView view,
            final int defaultImageResId,
            final int errorImageResId,
            final String url) {
        return new ImageListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (errorImageResId != 0) {
                    view.setImageResource(errorImageResId);
                }
            }

            @Override
            public void onResponse(ImageContainer response, boolean isImmediate) {
                if (response.getBitmap() != null) {
                    //在這裏可以設置,假設想獲得圓角圖片的畫,可以對bitmap進行加工,可以給imageview加一個
                    //額外的參數
                    String urlTag = (String) view.getTag();
                    if(urlTag!=null && urlTag.trim().equals(url)){
                        view.setImageBitmap(response.getBitmap());
                    }
                } else if (defaultImageResId != 0) {
                    view.setImageResource(defaultImageResId);
                }
            }
        };
    }

4、volley的詳細使用方法

  關於這塊內容。網絡上有許多的資料,總之volley使用起來很的簡單。感興趣的可以去網絡上查找相關的資料進行學習。volley的載入速度絕對出乎你的意料。

——知道本身是誰。要什麼。能跳多高。而且敢跳,並承受跳了可能失敗的所有結果。

相關文章
相關標籤/搜索