Android Volley 通信框架应用解析

来源:互联网 发布:mysql dba 常用sql 编辑:程序博客网 时间:2024/05/16 15:57

概述

Volley是2013年Google I/O大会上推出了一个全新的网络通信框架。它集合了AsyncHttpClient和Universal-Image-Loader的优点,可以非常简单的进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络图片。Volley的使用场景是进行数据量不大,但是通信频繁的网络操作,而对于大数据量的网络操作,比如文件下载等,Volley就不适合使用。

Volley的RequestQueue 和 Request

RequestQueue :一个线程池的请求调度队列。调用add(Request)方法将会执行给定的请求调度,解决从缓存或网络上的工作线程,然后在主线程中提供解析响应。
Request:所有的网络请求类的父类。
Request中直接的子类
StringRequest:后台返回的响应体为字符串
JsonRequest:以JSON的方式发送请求和接收的响应体为JSON对象,主要使用JsonArrayRequest和JsonObjectRequest两个类来实现。
ImageRequest:请求网络中的图片,返回的类型是Bitmap对象。

Volley的基本应用

首先在发起网络请求之前,必须构建一个RequestQueue 实例,由它来处理网络请求调度。
RequestQueue requestQueue = Volley.newRequestQueue(context);
RequestQueue 内部是一个线程池,不必每次网络请求都去创建该对象,只需要初始化一次就可以了。

StringRequest的用法

使用这种请求方式,后台服务器返回的响应体都是以字符串形式返回的。
代码实例:

StringRequest request = new StringRequest("http://www.baidu.com", new Listener<String>() {    @Override    public void onResponse(String response) {        // TODO Auto-generated method stub        Log.i("TAG", "===="+response);    }}, new ErrorListener() {    @Override    public void onErrorResponse(VolleyError error) {        // TODO Auto-generated method stub    }});requestQueue.add(request);

我们可以从上面代码中看到,实例化StringRequest时,构造函数中传入三个参数,第一个参数就是目标服务器的请求地址URL,第二个参数是服务器响应成功后的回调,第三个参数是服务器响应失败后的回调。最后,完成了StringRequest的实例化后,将该StringRequest添加到请求队列requestQueue中。调用requestQueue.add(request)这一步不能忘记。
你还可以设置网络访问方式,通过调用StringRequest request = new StringRequest(Method.POST, url, listener, errorListener);
以上就完成了StringRequest方式简单的访问网络。

JsonRequest的用法

StringRequest和JsonRequest都是继承自Request类的,而且JsonRequest是一个抽象类,不能直接创建对象。我们必须通过它的子类JsonArrayRequest和JsonObjectRequest来创建对象。使用方法和上面相同。
代码示例:

JsonObjectRequest request = new JsonObjectRequest(Method.GET, "http://m2.qiushibaike.com/article/list/suggest?page=1", null ,new Listener<JSONObject>() {    @Override    public void onResponse(JSONObject response) {        // TODO Auto-generated method stub        Log.i("TAG", "==="+response);    }}, new ErrorListener() {    @Override    public void onErrorResponse(VolleyError error) {        // TODO Auto-generated method stub    }});requestQueue.add(request);

上面便是JsonObjectRequest的使用方法,与StringRequest基本一致。你还可以在上面的第三个参数null中加入自己需要传递给服务器端的JSONObject对象,里面包含了你需要传递的参数。

ImageRequest的用法

ImageRequest主要是用来请求网络图片,返回的对象是Bitmap对象。可以直接将该对象设置到imageView控件中。
代码示例:

ImageRequest request = new ImageRequest("http://avatar.csdn.net/6/6/D/1_lfdfhl.jpg", new Listener<Bitmap>() {    @Override    public void onResponse(Bitmap response) {        // TODO Auto-generated method stub        imageView.setImageBitmap(response);    }}, 0, 0, ScaleType.CENTER_CROP, Config.RGB_565, new ErrorListener() {    @Override    public void onErrorResponse(VolleyError error) {        // TODO Auto-generated method stub    }} );requestQueue.add(request);

从上面可以知道,ImageRequest构造函数可以接受7个参数。第一个参数是目标服务器的请求地址,第二个参数是服务器响应成功后回调,返回的是Bitmap对象。第三个和四个参数是压缩网络图片的最大宽度和最大高度,第五个参数是指图片的缩放类型,第六个参数是解码图片的格式,第七个参数是服务器响应失败回调。

图片加载之ImageLoader的用法

我们知道使用ImageRequest就可以加载网络中的图片,但是这种加载方式并不高效而且没有有效利用缓存机制所以ImageRequest并不是最好的图片加载方式。ImageLoader是对ImageRequest的进一步封装,所以比它更高效,也支持图片缓存。
代码示例:

    ImageLoader imageLoader = new ImageLoader(requestQueue,    new MyBitmapCache());    ImageListener imageListener = ImageLoader.getImageListener(imageView, R.drawable.ic_launcher, R.drawable.ic_launcher);    imageLoader.get("http://img01.taopic.com/150920/240455-1509200H31810.jpg", imageListener, 300, 300, ScaleType.CENTER_CROP);    class MyBitmapCache implements ImageCache {        private LruCache<String, Bitmap> lruCache = null;        private MyBitmapCache() {            int memoryCount = (int) Runtime.getRuntime().maxMemory();            int cacheSize = memoryCount / 8; // 获取剩余内存的1/8作为缓存            lruCache = new LruCache<String, Bitmap>(cacheSize) {                @Override                protected int sizeOf(String key, Bitmap bitmap) {                    return bitmap.getRowBytes() * bitmap.getHeight();                }            };        }        @Override        public Bitmap getBitmap(String url) {            return lruCache.get(url);        }        @Override        public void putBitmap(String url, Bitmap bitmap) {            lruCache.put(url, bitmap);        }    }

从上面代码中可以看出,使用ImageLoader的方法需要执行四个步骤
1.创建RequestQueue 对象
2.创建ImageLoader对象,第一个参数为第一步创建的requestQueue,第二个参数为自定义的缓存类
3.创建ImageListener对象,通过调用ImageLoader.getImageListener的方法
4.调用ImageLoader实例的get方法。
以上便完成了使用ImageLoader加载网络图片的方式。

自定义Request的应用

使用自定义Request可以自行处理服务器返回的结果并定义返回的对象。重写Request需要继承Request类,然后重写parseNetworkResponse方法,该方法用来解析网络返回资源和返回一个相关的返回类型。重写deliverResponse方法,该方法主要是将返回的结果传送到监听Listener。这样就能在Listener的onResponse方法中获得该返回结果对象。
下面是我自己定义的用来处理JSONObject的Request类功能与JsonObjectRequest相同。
代码示例:

import java.io.UnsupportedEncodingException;import org.json.JSONException;import org.json.JSONObject;import com.android.volley.DefaultRetryPolicy;import com.android.volley.NetworkResponse;import com.android.volley.ParseError;import com.android.volley.Request;import com.android.volley.Response;import com.android.volley.Response.ErrorListener;import com.android.volley.Response.Listener;import com.android.volley.toolbox.HttpHeaderParser;public class HttpRequest extends Request<JSONObject> {    protected static final String PROTOCOL_CHARSET = "utf-8";    private static final String PROTOCOL_CONTENT_TYPE = String.format("application/json; charset=%s", PROTOCOL_CHARSET);    private Listener<JSONObject> listener;    private final String mRequestBody;    public HttpRequest(String tag, int method, String url,String mRequestBody,Listener<JSONObject> listener, ErrorListener errorListener) {        super(method, url, errorListener);        if (null != tag) {            setTag(tag);        }        setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 2, 1.0f));        this.listener = listener;        this.mRequestBody = mRequestBody;    }    @Override    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {        String parsed = null;        try {            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); //将服务器返回的字节数组转化为指定字符集格式的字符串        } catch (UnsupportedEncodingException e) {            parsed = new String(response.data);        }        try {            return Response.success(new JSONObject(parsed), HttpHeaderParser.parseCacheHeaders(response));        } catch (JSONException e) {             return Response.error(new ParseError(e));        }    }    @Override    protected void deliverResponse(JSONObject response) {        // TODO Auto-generated method stub        if (listener != null) {            listener.onResponse(response);        }    }    @Override    public String getBodyContentType() {        // TODO Auto-generated method stub        return PROTOCOL_CONTENT_TYPE;    }    @Override    public byte[] getBody() {        // TODO Auto-generated method stub        try {            return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);        } catch (UnsupportedEncodingException e) {            return null;        }    }}

这篇文章就对Volley的基本用法进行了介绍。下一篇文章将从源码的角度分析Volley。

1 0
原创粉丝点击