Android Volley 通信框架应用解析

概述

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值