Volly 框架簡介

、什麼是volley

         Volley是Ficus Kirpatrick在Gooogle I/O 2013發佈的一個處理和緩存網絡請求的庫,能使網絡通信更快,更簡單,更健壯。Volley名稱的由來: a burst or emission of many things or a large amount at once。在Google IO的演講上,其配圖是一幅發射火弓箭的圖,有點類似流星。見下圖

2、volley能做什麼

volley適合小而快的數據傳輸。Volley應該是簡化了網絡通信的一些開發,特別是針對以下兩種情況:

  • JSON對象
  • 圖片加載

Volley的便利功能:

Advantages of using Volley:

  1. Volley automatically schedule all network requests. It means that Volley will be taking care of all the network requests your app executes for fetching response or image from web.
  2. Volley provides transparent disk and memory caching.
  3. Volley provides powerful cancellation request API. It means that you can cancel a single request or you can set blocks or scopes of requests to cancel.
  4. Volley provides powerful customization abilities.
  5. Volley provides Debugging and tracing tools

3、volley架構

    Volley使用了線程池來作爲基礎結構,主要分爲主線程,cache線程和network線程。主線程和cache線程都只有一個,而NetworkDispatcher線程可以有多個,這樣能解決比並行問題。具體可以參考下圖,此圖節選自Google I/O 演講。




4、使用volley

4.1 獲取volley

引入Volley非常簡單,首先,從git庫先克隆一個下來:

  1. git clone https://android.googlesource.com/platform/frameworks/volley  

然後編譯爲jar包,再在自己的工程裏import進來。如果git下載失敗可以在這下載。 VolleyLib


4.2 JsonObjectRequest 簡單文本請求

         使用下面的代碼實現json數據獲取
mRequestQueue =  Volley.newRequestQueue(this);  
      String url = "http://pipes.yahooapis.com/pipes/pipe.run?_id=giWz8Vc33BG6rQEQo_NLYQ&_render=json";  
      pd = ProgressDialog.show(this,"Please Wait...","Please Wait...");  
        
      JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET,url,null,new Response.Listener<JSONObject>() {  
          @Override  
          public void onResponse(JSONObject response) {  
              Log.i(TAG,response.toString());  
              parseJSON(response);  
              va.notifyDataSetChanged();  
              pd.dismiss();  
          }  
      },new Response.ErrorListener() {  
          @Override  
          public void onErrorResponse(VolleyError error) {  
              Log.i(TAG,error.getMessage());  
          }  
      });  
      mRequestQueue.add(jr);  





4.3 ImageView

        使用volley異步加載圖像
RequestQueue mRequestQueue = Volley.newRequestQueue(this);  
        final LruCache<String, Bitmap> mImageCache = new LruCache<String, Bitmap>(  
                20);  
        ImageCache imageCache = new ImageCache() {  
            @Override  
            public void putBitmap(String key, Bitmap value) {  
                mImageCache.put(key, value);  
            }  
  
            @Override  
            public Bitmap getBitmap(String key) {  
                return mImageCache.get(key);  
            }  
        };  
        ImageLoader mImageLoader = new ImageLoader(mRequestQueue, imageCache);  
        // imageView是一個ImageView實例  
        // ImageLoader.getImageListener的第二個參數是默認的圖片resource id  
        // 第三個參數是請求失敗時候的資源id,可以指定爲0  
        ImageListener listener = ImageLoader  
                .getImageListener(imageView, android.R.drawable.ic_menu_rotate,  
                        android.R.drawable.ic_delete);  
        mImageLoader.get("http://a.hiphotos.baidu.com/album/h%3D800%3Bcrop%3D0%2C0%2C1280%2C800/sign=5f024b518326cffc762ab2b2893a29e2/72f082025aafa40fa3bcf315aa64034f79f019fb.jpg", listener);  



4.4 NetworkImageView

NetworkImageView是繼承自ImageView,是Volley提供的一個全新的簡單加載圖片的控件。

NetworkImageView netImgView=(NetworkImageView)findViewById(R.id.volley_img_networkimgeview);  
        netImgView.setTag("url");  
          
        netImgView.setImageUrl("http://a.hiphotos.baidu.com/album/h%3D800%3Bcrop%3D0%2C0%2C1280%2C800/sign=5f024b518326cffc762ab2b2893a29e2/72f082025aafa40fa3bcf315aa64034f79f019fb.jpg",mImageLoader);  



4.4 NetworkImageView

NetworkImageView是繼承自ImageView,是Volley提供的一個全新的簡單加載圖片的控件。

NetworkImageView netImgView=(NetworkImageView)findViewById(R.id.volley_img_networkimgeview);  
        netImgView.setTag("url");  
          
        netImgView.setImageUrl("http://a.hiphotos.baidu.com/album/h%3D800%3Bcrop%3D0%2C0%2C1280%2C800/sign=5f024b518326cffc762ab2b2893a29e2/72f082025aafa40fa3bcf315aa64034f79f019fb.jpg",mImageLoader);  


1、獲取JSON對象

1.1聲明RequestQueue

聲明一個新的RequestQueue對象
private RequestQueue mRequestQueue;  
onCreate初始化mRequestQueue
mRequestQueue =  Volley.newRequestQueue(this);


1.2 聲明並使用Request
JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET,url,null,new Response.Listener<JSONObject>() {  
            @Override  
            public void onResponse(JSONObject response) {  
                Log.i(TAG,response.toString());  
                parseJSON(response);  
                va.notifyDataSetChanged();  
                pd.dismiss();  
            }  
        },new Response.ErrorListener() {  
            @Override  
            public void onErrorResponse(VolleyError error) {  
                Log.i(TAG,error.getMessage());  
            }  
        });  
        mRequestQueue.add(jr);  



Volley提供了JsonObjectRequest、JsonArrayRequest、StringRequest等Request形式。

JsonObjectRequest:返回JSON對象。

JsonArrayRequest:返回JsonArray。

StringRequest:返回String,這樣可以自己處理數據,更加靈活。

另外可以繼承Request<T>自定義Request。


1.3 取消Request

      Activity裏面啓動了網絡請求,而在這個網絡請求還沒返回結果的時候,Activity被結束了,此時如果繼續使用其中的Context等,除了無辜的浪費CPU,電池,網絡等資源,有可能還會導致程序crash,所以,我們需要處理這種一場情況。使用Volley的話,我們可以在Activity停止的時候,同時取消所有或部分未完成的網絡請求。Volley裏所有的請求結果會返回給主進程,如果在主進程裏取消了某些請求,則這些請求將不會被返回給主線程。Volley支持多種request取消方式。
1)可以針對某些個request做取消操作:
@Override  
   public void onStop() {  
       for (Request <?> req : mRequestQueue) {  
           req.cancel();  
       }  
   }  


2)取消這個隊列裏的所有請求:
@Override  
protected void onStop() {  
    // TODO Auto-generated method stub  
    super.onStop();  
    mRequestQueue.cancelAll(this);  
}  


3)可以根據RequestFilter或者Tag來終止某些請求
@Override  
rotected void onStop() {  
// TODO Auto-generated method stub  
super.onStop();  
  
mRequestQueue.cancelAll( new RequestFilter() {});  
or  
mRequestQueue.cancelAll(new Object());  
  



Volley支持http的GET、POST、PUT、DELETE等方法,上面給出了GET方法,其他方法請參考



2、圖片加載

2.1使用ImageRequest下載圖片

    Volley提供了多種Request方法,ImageRequest能夠處理單張圖片,返回bitmap。下面是ImageRequest的使用例子,和JsonRequest的一樣。
singleImg=(ImageView)findViewById(R.id.volley_img_single_imgeview);  
        ImageRequest imgRequest=new ImageRequest(url, new Response.Listener<Bitmap>() {  
            @Override  
            public void onResponse(Bitmap arg0) {  
                // TODO Auto-generated method stub  
                singleImg.setImageBitmap(arg0);  
            }  
        }, 300, 200, Config.ARGB_8888, new ErrorListener(){  
            @Override  
            public void onErrorResponse(VolleyError arg0) {  
                // TODO Auto-generated method stub  
                  
            }             
        });  
        mRequestQueue.add(imgRequest);  



2.2使用ImageLoader

    ImageLoader這個類需要一個Request的實例以及一個ImageCache的實例。圖片通過一個URL和一個ImageListener實例的get()方法就可以被加載。從哪裏,ImageLoader會檢查ImageCache,而且如果緩存裏沒有圖片就會從網絡上獲取。

    Volley的ImageCache接口允許你使用你喜歡的L1緩存實現。不幸的是Volley沒有提供默認的實現。在I/O的介紹中展示了BitmapLruCache的一點代碼片段,但是Volley這個庫本身並不包含任何相關的實現。

    ImageCache接口有兩個方法,getBitmap(String url)和putBitmap(String url, Bitmap bitmap).這兩個方法足夠簡單直白,他們可以添加任何的緩存實現。

RequestQueue mRequestQueue = Volley.newRequestQueue(this);  
        final LruCache<String, Bitmap> mImageCache = new LruCache<String, Bitmap>(  
                20);  
        ImageCache imageCache = new ImageCache() {  
            @Override  
            public void putBitmap(String key, Bitmap value) {  
                mImageCache.put(key, value);  
            }  
  
            @Override  
            public Bitmap getBitmap(String key) {  
                return mImageCache.get(key);  
            }  
        };  
        ImageLoader mImageLoader = new ImageLoader(mRequestQueue, imageCache);  
        // imageView是一個ImageView實例  
        // ImageLoader.getImageListener的第二個參數是默認的圖片resource id  
        // 第三個參數是請求失敗時候的資源id,可以指定爲0  
        ImageListener listener = ImageLoader  
                .getImageListener(imageView, android.R.drawable.ic_menu_rotate,  
                        android.R.drawable.ic_delete);  
        mImageLoader.get(url, listener);


2.3 使用NetworkImageView

public class NetworkImageView extends ImageView  

繼承自ImageView,添加了一個
public void setImageUrl(String url, ImageLoader imageLoader) {}  
方法,參數包含一個Url地址和一個ImageLoader對象
核心方法:
private void loadImageIfNecessary(final boolean isInLayoutPass) {}


內部實現,boolean 類型參數代表是否重新請求網絡 ,true:重新請求 false:取緩存
內部實現和ImageLoader類似,都是通過ImageContainer中new一個ImageListener,在ImageListener,只是做了Url的空判斷,如果Url爲null,則調用ImageContainer.cancelRequest();取消請求。
覆寫方法:
 
@Override  
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {  
super.onLayout(changed, left, top, right, bottom);  
//onLayout時重新請求  
loadImageIfNecessary(true);  
}  
@Override  
protected void onDetachedFromWindow() {  
//銷燬View的時候Release操作  
if (mImageContainer != null) {  
// If the view was bound to an image request, cancel it and clear  
// out the image from the view.  
mImageContainer.cancelRequest();  
setImageBitmap(null);  
// also clear out the container so we can reload the image if necessary.  
mImageContainer = null;  
}  
super.onDetachedFromWindow();  
}  
//drawable狀態改變重繪  
@Override  
protected void drawableStateChanged() {  
super.drawableStateChanged();  
invalidate();  
}  


    總結:網絡請求下載圖片顯示,可以使用此控件,比傳統的ImageView多了網絡處理,也添加了2個方法,設置開始下載的默認圖和下載出錯後顯示圖。
/** 
* Sets the default image resource ID to be used for this view until the attempt to load it 
* completes. 
*/  
public void setDefaultImageResId(int defaultImage) {  
mDefaultImageId = defaultImage;  
}  
/** 
* Sets the error image resource ID to be used for this view in the event that the image 
* requested fails to load. 
*/  
public void setErrorImageResId(int errorImage) {  
mErrorImageId = errorImage;  
}  


 

4.4 NetworkImageView

NetworkImageView是繼承自ImageView,是Volley提供的一個全新的簡單加載圖片的控件。

NetworkImageView netImgView=(NetworkImageView)findViewById(R.id.volley_img_networkimgeview);  
        netImgView.setTag("url");  
          
        netImgView.setImageUrl("http://a.hiphotos.baidu.com/album/h%3D800%3Bcrop%3D0%2C0%2C1280%2C800/sign=5f024b518326cffc762ab2b2893a29e2/72f082025aafa40fa3bcf315aa64034f79f019fb.jpg",mImageLoader);  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章