Android 开源框架 ( 六 ) Volley --- Google的轻量级网络通信框架
一.Volley介绍
2013年Google I/O大会上推出的一个新的Android网络通信框架,目标是将HTTP的通信操作再进行简单化,除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。不过谷歌已经停止更新Volley了,现在OkHttp成为新一代网络通信的新宠。
二.Volley使用
1.导入jar包
如果只是用于学习,可以通过gradle引用 compile 'com.mcxiaoke.volley:library:1.0.19' 了解下.但是如果用于项目中,最好下载Google官方的jar包.
compile 'com.mcxiaoke.volley:library:1.0.19'
2.授权
<uses-permission android:name="android.permission.INTERNET" />
3.使用JsonObjectRequest get请求方式示例
//1.创建一个请求队列RequestQueue RequestQueue queue= Volley.newRequestQueue(this); //2.创建StringRequest对象 JsonObjectRequest request=new JsonObjectRequest(url, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { //接收返回数据 Log.e("success",jsonObject.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { } }); //3.将请求对象添加到请求队列中 queue.add(request);
同样还有一些其他请求:ClearCacheRequest,ImageRequest,JsonArrayRequest,JsonRequest,StringRequest 用法一样.

1.ClearCacheRequest :A synthetic request used for clearing the cache. 用于清除缓存请求类
2.ImageRequest :A canned request for getting an image at a given URL and calling back with a decoded Bitmap. 通过Url获取对应解码位图decoded BitMap 请求类
3.JsonArrayRequest :A request for retrieving a {@link JSONArray} response body at a given URL. 通过Url返回一个{@ Link JSONArray}Json数组请求类
4.JsonObjectRequest :A request for retrieving a {@link JSONObject} response body at a given URL, allowing for an optional {@link JSONObject} to be passed in as part of the request body. 可以通过Url返回一个{@link JSONObject},也可以使用{@link JSONObject}当做请求Request的传递参数.
5.JsonRequest :A request for retrieving a T type response body at a given URL that also optionally sends along a JSON body in the request specified. 通过Url返回一个定义的泛型T ,也可以使用JSON当做请求Request的传递参数的类
6.StringRequest :A canned request for retrieving the response body at a given URL as a String. 通过Url返回一个String字符串请求类
4.使用JsonObjectRequest post请求方式示例
Post请求,只需要在Request请求里,添加一个参数Request.Method.POST : new JsonObjectRequest(Request.Method.POST,url, new Response.Listener<JSONObject>() {...});其他部分一样.
RequestQueue queue= Volley.newRequestQueue(this); JsonObjectRequest request=new JsonObjectRequest(Request.Method.POST,url, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { //接收返回数据 Log.e("success",jsonObject.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { } }); queue.add(request);
通过Request.Method.能看到Volley支持的一些请求方式:

5.HurlStack 与 HttpClientStack 介绍
Volley是官方出的,volley在设计的时候是将具体的请求客户端做了下封装,也就是说可以支持HttpUrlConnection, HttpClient.当然也可以自己封装支持OkHttp.
Volley.java类
if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { //HttpURLConnection 请求方式 stack = new HurlStack(); } else { // Prior to Gingerbread, HttpUrlConnection was unreliable. // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html //HttpClient 请求方式 stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } }
然后具体看下 HurlStack.java 里的HttpUrlConnection请求封装.
/**
* An {@link HttpStack} based on {@link HttpURLConnection}.
*/
public class HurlStack implements HttpStack {
private static final String HEADER_CONTENT_TYPE = "Content-Type";
/**
* Create an {@link HttpURLConnection} for the specified {@code url}.
*/
protected HttpURLConnection createConnection(URL url) throws IOException {
return (HttpURLConnection) url.openConnection();
}
/**
* Opens an {@link HttpURLConnection} with parameters.
* @param url
* @return an open connection
* @throws IOException
*/
private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException {
HttpURLConnection connection = createConnection(url);
int timeoutMs = request.getTimeoutMs();
connection.setConnectTimeout(timeoutMs);
connection.setReadTimeout(timeoutMs);
connection.setUseCaches(false);
connection.setDoInput(true);
// use caller-provided custom SslSocketFactory, if any, for HTTPS
if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
}
return connection;
}
@SuppressWarnings("deprecation")
/* package */ static void setConnectionParametersForRequest(HttpURLConnection connection,
Request<?> request) throws IOException, AuthFailureError {
switch (request.getMethod()) {
case Method.DEPRECATED_GET_OR_POST:
// This is the deprecated way that needs to be handled for backwards compatibility.
// If the request's post body is null, then the assumption is that the request is
// GET. Otherwise, it is assumed that the request is a POST.
byte[] postBody = request.getPostBody();
if (postBody != null) {
// Prepare output. There is no need to set Content-Length explicitly,
// since this is handled by HttpURLConnection using the size of the prepared
// output stream.
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty(HEADER_CONTENT_TYPE,
request.getPostBodyContentType());
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(postBody);
out.close();
}
break;
case Method.GET:
// Not necessary to set the request method because connection defaults to GET but
// being explicit here.
connection.setRequestMethod("GET");
break;
case Method.DELETE:
connection.setRequestMethod("DELETE");
break;
case Method.POST:
connection.setRequestMethod("POST");
addBodyIfExists(connection, request);
break;
case Method.PUT:
connection.setRequestMethod("PUT");
addBodyIfExists(connection, request);
break;
case Method.HEAD:
connection.setRequestMethod("HEAD");
break;
case Method.OPTIONS:
connection.setRequestMethod("OPTIONS");
break;
case Method.TRACE:
connection.setRequestMethod("TRACE");
break;
case Method.PATCH:
connection.setRequestMethod("PATCH");
addBodyIfExists(connection, request);
break;
default:
throw new IllegalStateException("Unknown method type.");
}
}
private static void addBodyIfExists(HttpURLConnection connection, Request<?> request)
throws IOException, AuthFailureError {
byte[] body = request.getBody();
if (body != null) {
connection.setDoOutput(true);
connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType());
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(body);
out.close();
}
}
}
在看看HttpClientStack.java 里的HttpClient的封装. 注意下哈,HttpClient 已经在Android 6.0 删除.
/** * An HttpStack that performs request over an {@link HttpClient}. */ public class HttpClientStack implements HttpStack { protected final HttpClient mClient; private final static String HEADER_CONTENT_TYPE = "Content-Type"; /** * Creates the appropriate subclass of HttpUriRequest for passed in request. */ @SuppressWarnings("deprecation") /* protected */ static HttpUriRequest createHttpRequest(Request<?> request, Map<String, String> additionalHeaders) throws AuthFailureError { switch (request.getMethod()) { case Method.DEPRECATED_GET_OR_POST: { // This is the deprecated way that needs to be handled for backwards compatibility. // If the request's post body is null, then the assumption is that the request is // GET. Otherwise, it is assumed that the request is a POST. byte[] postBody = request.getPostBody(); if (postBody != null) { HttpPost postRequest = new HttpPost(request.getUrl()); postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType()); HttpEntity entity; entity = new ByteArrayEntity(postBody); postRequest.setEntity(entity); return postRequest; } else { return new HttpGet(request.getUrl()); } } case Method.GET: return new HttpGet(request.getUrl()); case Method.DELETE: return new HttpDelete(request.getUrl()); case Method.POST: { HttpPost postRequest = new HttpPost(request.getUrl()); postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setEntityIfNonEmptyBody(postRequest, request); return postRequest; } case Method.PUT: { HttpPut putRequest = new HttpPut(request.getUrl()); putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setEntityIfNonEmptyBody(putRequest, request); return putRequest; } case Method.HEAD: return new HttpHead(request.getUrl()); case Method.OPTIONS: return new HttpOptions(request.getUrl()); case Method.TRACE: return new HttpTrace(request.getUrl()); case Method.PATCH: { HttpPatch patchRequest = new HttpPatch(request.getUrl()); patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType()); setEntityIfNonEmptyBody(patchRequest, request); return patchRequest; } default: throw new IllegalStateException("Unknown request method."); } } }
浙公网安备 33010602011771号