在Volley类中创建RequestQueue的时候,Volley就会根据设备的SDK版本来创建不同的HttpStack接口实现类,分别是HurlStack和HttpClientStack。
if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { stack = new HurlStack(); } else { stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } }
而在前面的章节中讲到,在BasicNetwork中,其实真正去跟网络打交道的正是这两个对象,在BasicNetwork, 调用HttpStack的performRequest方法,
public NetworkResponse performRequest(Request<?> request) throws VolleyError { ... httpResponse = mHttpStack.performRequest(request, headers);
由于HurlStack和HttpClientStack的实现机制是一样的,只是使用的类不一样,我们这篇文章就只讲解HurlStack了。
下面是HurlStack中performRequest方法,
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());//默认为null map.putAll(additionalHeaders);//添加头部,主要是缓存相关的头部信息 if (mUrlRewriter != null) { ...//代码不执行 } URL parsedUrl = new URL(url); HttpURLConnection connection = openConnection(parsedUrl, request);//打开Connection for (String headerName : map.keySet()) { connection.addRequestProperty(headerName, map.get(headerName)); }//将Map的对象添加到Connection的属性中 setConnectionParametersForRequest(connection, request);//设置connection方法,主要是设置Method属性和Content(for post/put) // Initialize HttpResponse with data from the HttpURLConnection. ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);//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));将返回的内容解析成response的Entity对象 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; }HttpURLConnection是Android3.0以后才提供的一个网络访问类,而HurlStack类,也正是H(ttp)URL的缩写,所以这个类,其实就是基于HttpUrlConnection的实现,其步骤如下:
1)从Request中获得url参数,根据url参数构造URL对象,而URL对象是java提供的获取网络资源的一个封装好的实用类。
2)从URL对象打开Connection,并设置connection的超时,缓存,让网络资源写入等属性。
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; }3)调用方法 setConnectionParametersForRequest 来设置 Method属性,如果是Post或者Put的话,还要设置Content内容。
4)设置Http 协议,这里基本上是1.1了。
5)获得Response的流,并将其解析成对应的HttpEntity对象,设置给Response.entity字段,返回给BasicNetwork。
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; }
6)BasicNetwork获得返回来的Response对象,就会由Request去解析这个Response对象,因为不同的请求返回来的对象是不一样的,所以这个解析的过程必须由各个请求的实现类自己去实现,也即如ImageRequest,JsonObjectRequest对象等,都要实现自己的parseNetworkResponse方法。
HurlStack提供了三个构造函数,如下:
public HurlStack() { this(null); } /** * @param urlRewriter Rewriter to use for request URLs */ public HurlStack(UrlRewriter urlRewriter) { this(urlRewriter, null); } /** * @param urlRewriter Rewriter to use for request URLs * @param sslSocketFactory SSL factory to use for HTTPS connections */ public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) { mUrlRewriter = urlRewriter; mSslSocketFactory = sslSocketFactory; }
其中第一个就是Volley类中使用的构造函数,但其实最终调用的都是
public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) { mUrlRewriter = urlRewriter; mSslSocketFactory = sslSocketFactory; }
结束。
Android中关于Volley的使用(九)认识HurlStack(HttpClientStack),布布扣,bubuko.com