Volley框架的基本解读
Posted zero_zero_zero_zero
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Volley框架的基本解读相关的知识,希望对你有一定的参考价值。
废话不多说,放上Volley框架的基本解读(三)的链接,我们继续往下看,先来看看网络执行类HttpStack的源码:
/**
* An HTTP stack abstraction.
*/
public interface HttpStack
/**
* Performs an HTTP request with the given parameters.
*
* <p>A GET request is sent if request.getPostBody() == null. A POST request is sent otherwise,
* and the Content-Type header is set to request.getPostBodyContentType().</p>
*
* @param request the request to perform
* @param additionalHeaders additional headers to be sent together with
* @link Request#getHeaders()
* @return the HTTP response
*
* 真正的网络请求
*/
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
throws IOException, AuthFailureError;
这是一个接口,里面有一个与Network接口同名,但又不一样的方法。
具体实现是由Volley.newRequestQueue中根据api版本不同,创建的HurlStack或HttpClientStack,前面已经说过两者之间的差别,我们选版本高的来讲,这里值得一提的是,之所以在api9之后不用HttpClient,是因为它有所缺陷,好了,进入正题:
public HurlStack()
this(null);
继续看:
public HurlStack(UrlRewriter urlRewriter)
this(urlRewriter, null);
再看:
public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory)
mUrlRewriter = urlRewriter;
mSslSocketFactory = sslSocketFactory;
UrlRewriter是HurlStack中的一个内部接口,用于URL的重置,我们给的是null,所以不用管它,SSLSocketFactory是https协议用到的类,我们给的也是null,所以也不需要管它,直入主题看performRequest方法:
@Override
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
throws IOException, AuthFailureError
String url = request.getUrl();
HashMap<String, String> map = new HashMap<String, String>();
map.putAll(request.getHeaders());
map.putAll(additionalHeaders);
if (mUrlRewriter != null)
String rewritten = mUrlRewriter.rewriteUrl(url);
if (rewritten == null)
throw new IOException("URL blocked by rewriter: " + url);
url = rewritten;
URL parsedUrl = new URL(url);
HttpURLConnection connection = openConnection(parsedUrl, request);
// 添加请求头
for (String headerName : map.keySet())
connection.addRequestProperty(headerName, map.get(headerName));
setConnectionParametersForRequest(connection, request);
// Initialize HttpResponse with data from the HttpURLConnection.
ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
int responseCode = connection.getResponseCode();
if (responseCode == -1)
// -1 is returned by getResponseCode() if the response code could not be retrieved.
// Signal to the caller that something was wrong with the connection.
throw new IOException("Could not retrieve response code from HttpUrlConnection.");
StatusLine responseStatus = new BasicStatusLine(protocolVersion,
connection.getResponseCode(), connection.getResponseMessage());
BasicHttpResponse response = new BasicHttpResponse(responseStatus);
response.setEntity(entityFromConnection(connection));
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet())
if (header.getKey() != null)
Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
response.addHeader(h);
return response;
前面都很简单,我们直接看第16行的openConnection方法:
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
// 如果是https协议
if ("https".equals(url.getProtocol()) && mSslSocketFactory != null)
((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
return connection;
再看createConnection方法:
protected HttpURLConnection createConnection(URL url) throws IOException
return (HttpURLConnection) url.openConnection();
很简单吧,仅仅只是封装了(HttpURLConnection) url.openConnection()这一句代码而已,那么上面也就简单了,只是对网络请求进行了一些简单的设置,判断是否是https协议,进行设置。
这里提一点request.getTimeoutMs()获取到的时间其实是DefaultRetryPolicy中mCurrentTimeoutMs,当请求重试时,连接超时的时间会被延长。
随后就是添加请求头,setConnectionParametersForRequest方法用于确定请求方式:
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;
default:
throw new IllegalStateException("Unknown method type.");
包含GET,DELETE,POST,PUT等等,第一种请无视它,大概的意思是这是过时的,需要处理的向后兼容性,如果该请求的正文无效,则该假设是该请求是GET,否则是POST,老实说我也不知道它想表达什么意思,如果有大神知道还望指教!
之后就是为了统一返回方式,将HttpURLConnection中的属性给予了封装,先是http协议版本,然后封装成状态行,再然后放入BasicHttpResponse中,设置实体,entityFromConnection方法,猜也猜的到是做什么用的:
/**
* Initializes an @link HttpEntity from the given @link HttpURLConnection.
* @param connection
* @return an HttpEntity populated with data from <code>connection</code>.
*
* 将HttpURLConnection换成HttpEntity
*/
private static HttpEntity entityFromConnection(HttpURLConnection connection)
BasicHttpEntity entity = new BasicHttpEntity();
InputStream inputStream;
try
inputStream = connection.getInputStream();
catch (IOException ioe)
inputStream = connection.getErrorStream();
entity.setContent(inputStream);
entity.setContentLength(connection.getContentLength());
entity.setContentEncoding(connection.getContentEncoding());
entity.setContentType(connection.getContentType());
return entity;
很简单,我就不废话了。
最后添加响应头,一个HttpResponse就封装完成了。
到此Volley网络请求这一条线,我们已经全部走完了,希望各位读者能有所收获!
以上是关于Volley框架的基本解读的主要内容,如果未能解决你的问题,请参考以下文章