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的演讲上,其配图是一幅发射火弓箭的图,有点类似流星。见下图

Volly 框架简介_第1张图片

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 演讲。


Volly 框架简介_第2张图片


4、使用volley

4.1 获取volley

引入Volley非常简单,首先,从git库先克隆一个下来:

[html]  view plain copy print ?
  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() {  
          @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 mImageCache = new LruCache(  
                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() {  
            @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() {  
            @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 mImageCache = new LruCache(  
                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);  

你可能感兴趣的:(【android,框架】)