概述
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。