volley的简单使用

来源:互联网 发布:sql语句创建表 编辑:程序博客网 时间:2024/04/27 17:11

volley的特性:

JSON,图像等的异步下载;

网络请求的排序(scheduling

网络请求的优先级处理

缓存

多级别取消请求

Activity和生命周期的联动(Activity结束时同时取消所有网络请求)

 

接下来,我们来学习简单的使用下volley给我提供的API吧。

 

1.首先拿到一个请求队列(RequestQueue只需要一个实例即可,不像AsyncTask每次使用都要new一个)

// 初始化RequestQueue一个activity只需要一个

private voidinitRequestQueue() {

mQueue = Volley.newRequestQueue(getApplicationContext());

}


2.实现volley的异步请求类(JsonObjectRequest,JsonArrayRequest,StringRequest,ImageRequest

由于用法都相差不大,我就不一一举例了,举几个常用有代表性的例子:

 

以下代码是StringRequestget请求:

Private   void   loadGetStr(String url)  {

StringRequestsrReq = new StringRequest(Request.Method.GET, url,

new StrListener(),new StrErrListener()) {

protectedfinal String TYPE_UTF8_CHARSET = "charset=UTF-8";

// 重写parseNetworkResponse方法改变返回头参数解决乱码问题

// 主要是看服务器编码,如果服务器编码不是UTF-8的话那么就需要自己转换,反之则不需要

@Override

protectedResponse<String> parseNetworkResponse( NetworkResponse response) {

try{

String type = response.headers.get(HTTP.CONTENT_TYPE);

if (type == null) {

type = TYPE_UTF8_CHARSET;

response.headers.put(HTTP.CONTENT_TYPE, type);

} else if (!type.contains("UTF-8")) {

type += ";" + TYPE_UTF8_CHARSET;

response.headers.put(HTTP.CONTENT_TYPE, type);

}

}catch (Exception e) {

}

returnsuper.parseNetworkResponse(response);

};

srReq.setShouldCache(true); // 控制是否缓存

startVolley(srReq);

}


以下代码是JsonObjectRequestpost请求:

Private   void   loadPostJson(String url) {

// 第二个参数说明:

// 默认情况下设成nullget方法,否则为post方法

JsonObjectRequest srReq =new JsonObjectRequest(url,null,

new JsonListener(), new StrErrListener()){

@Override

protectedMap<String, String> getParams() throws AuthFailureError {

Map<String, String> map = new HashMap<String,String>();

map.put("w", "2459115");

map.put("u", "f");

return map;

}

};

srReq.setShouldCache(false);// 控制是否缓存

startVolley(srReq);

}


大家注意看的话,无论是JsonObjectRequespost还是StringRequestget需要传入两个监听函数一个是成功一个是失败,成功监听他们会返回相应类型的数据:

// StringRequest请求成功回调

private class StrListener implements Listener<String> {

 

@Override

public voidonResponse(String arg0) {

Log.e(Tag, arg0);

}

}

 

// JsonObjectReques请求成功回调

private class GsonListenerimplements Listener<ErrorRsp> {

 

@Override

public voidonResponse(ErrorRsp arg0) {

Toast.makeText(mContext,arg0.toString(), Toast.LENGTH_LONG).show();

}

}

// 共用失败回调

private class StrErrListener implementsErrorListener {

 

@Override

public voidonErrorResponse(VolleyError arg0) {

Toast.makeText(mContext,

VolleyErrorHelper.getMessage(arg0,mContext),

Toast.LENGTH_LONG).show();

}

}

      

接下来是ImageRequest

/**

* 第三第四个参数分别用于指定允许图片最大的宽度和高度,如果指定的网络图片的宽度或高度大于这里的最大值,则会对图片进行压缩,

* 指定成0的话就表示不管图片有多大,都不会进行压缩。

*

* @param url

* 图片地址

* @param listener

* @param maxWidth

* 指定允许图片最大的宽度

* @param maxHeight

* 指定允许图片最大的高度

* @param decodeConfig

* 指定图片的颜色属性,Bitmap.Config下的几个常量.

* @param errorListener

*/

private voidgetImageRequest(final ImageView iv, String url) {

 

ImageRequest  imReq = new  ImageRequest(url, new Listener<Bitmap>(){

@Override

public void onResponse(Bitmap arg0) {

iv.setImageBitmap(arg0);

}

}, 60, 60,Bitmap.Config.ARGB_8888, new StrErrListener());

startVolley(imReq);

}

      

看到现在大家肯定会疑惑写了这么多不同类型的Request到底如何运行?接下请看:

// 添加及开始请求

Private  void  startVolley(Request req) {

// 设置超时时间

// req.setRetryPolicy(newDefaultRetryPolicy(20 * 1000, 1, 1.0f));

// 将请求加入队列

mQueue.add(req);

// 开始发起请求

mQueue.start();

}

 

volley不仅提供了这些请求的方式,还提供了加载图片的一些方法和控件:

比如我们一个列表需要加载很多图片我们可以使用volley给我们提供的ImageLoader ImageLoaderImageRequest更加高效,因为它不仅对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。)

 

public  class  ImageAdapter extends  ArrayAdapter<String> {

 

private RequestQueue mQueue;

private ImageLoadermImageLoader;

 

public ImageAdapter(Contextcontext, List<String> objects) {

super(context,0, objects);

mQueue =Volley.newRequestQueue(getContext());

mImageLoader = new ImageLoader(mQueue, new BitmapCache());

}

 

@Override

public View getView(intposition, View convertView, ViewGroup parent) {

Stringurl = getItem(position);

ImageViewimageView;

if(convertView == null) {

imageView = new ImageView(getContext());

}else {

imageView= (ImageView) convertView;

}

//getImageListenerimageView控件对象,默认图片地址,失败图片地址);

ImageListenerlistener = ImageLoader.getImageListener(imageView,android.R.drawable.ic_menu_rotate, android.R.drawable.ic_delete);

//get(图片地址,listener,宽,高);自动帮你处理图片的宽高再也不怕大图片的oom

mImageLoader.get(url,listener,100,200);

returnimageView;

}

}

 

当然还需要重写ImageCache这个类

//使用LruCache再也不用怕加载多张图片oom

 

public  class BitmapCache extends LruCache<String,Bitmap> implements ImageCache {

// LruCache 原理:Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。当cache已满的时候加入新的item时,在队列尾部的item会被回收。

// 解释:当超出指定内存值则移除最近最少用的图片内存

public static intgetDefaultLruCacheSize() {

// 拿到最大内存

final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);

// 拿到内存的八分之一来做图片内存缓存

final int cacheSize =maxMemory / 8;

 

return cacheSize;

}

 

public BitmapLruCache() {

this(getDefaultLruCacheSize());

}

 

public BitmapLruCache(intsizeInKiloBytes) {

super(sizeInKiloBytes);

}

 

@Override

protected int sizeOf(Stringkey, Bitmap value) {

return value.getRowBytes() *value.getHeight() / 1024;

}

 

@Override

public Bitmap getBitmap(Stringurl) {

return get(url);

}

 

@Override

public void putBitmap(Stringurl, Bitmap bitmap) {

put(url, bitmap);

}

}


Volley还提供的加载图片的控件com.android.volley.NetworkImageView。(这个控件在被从父控件detach的时候,会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题,而且NetworkImageView还会根据你对图片设置的widthheigh自动压缩该图片不会产生多的内存,还有NetworkImageView在列表中使用不会图片错误)

 

<com.android.volley.toolbox.NetworkImageView

android:id="@+id/network_image_view"

android:layout_width="100dp"

android:layout_height="100dp"/>

    <com.android.volley.toolbox.NetworkImageView

       android:id="@+id/network_image_view"

        android:layout_width="100dp"

        android:layout_height="100dp"/>

使用方法:

[java] view plaincopyprint?

private voidnetworkImageViewUse(NetworkImageView iv, String url) {

ImageLoader imLoader = newImageLoader(mQueue, new BitmapLruCache());

iv.setDefaultImageResId(R.drawable.ic_launcher);

iv.setErrorImageResId(R.drawable.ic_launcher);

iv.setImageUrl(url, imLoader);

}

private voidnetworkImageViewUse(NetworkImageView iv, String url) {

              ImageLoader imLoader = new ImageLoader(mQueue, newBitmapLruCache());

              iv.setDefaultImageResId(R.drawable.ic_launcher);

              iv.setErrorImageResId(R.drawable.ic_launcher);

              iv.setImageUrl(url, imLoader);

       }


我们说了这么多都是请求,那么如何取消请求呢?

1.activity自动销毁时它会自定取消所有请求。

2.给请求设置标签:

 

request.setTag("MyTag"); 

取消所有指定标记的请求:

request.cancelAll("MyTag");

 

Volley的架构设计:


其中蓝色部分代表主线程,绿色部分代表缓存线程,橙色部分代表网络线程。我们在主线程中调用RequestQueueadd()方法来添加一条网络请求,这条请求会先被加入到缓存队列当中,如果发现可以找到相应的缓存结果就直接读取缓存并解析,然后回调给主线程。如果在缓存中没有找到结果,则将这条请求加入到网络请求队列中,然后处理发送HTTP请求,解析响应结果,写入缓存,并回调主线程。

 

0 0
原创粉丝点击