在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;    }

默认这两个类都是为null的,但是如果我们要实现对Url的拦截,对url进行一些处理的话,或者利用Https来保证数据传输的安全性的话,我们就可以传入自己实现的UrlRewriterc对象,或者添加SSlSocketFactory。不过在我们一般的项目中,也是用不到的啦,只要稍微了解一下就好了。
结束。

更多相关文章

  1. Android使用newInstance()实例化fragment&setArguments()传递参
  2. Android(安卓)Gson深入分析
  3. (Android、Java) AES加密方法
  4. Android(安卓)Studio用法之ListView(图文并茂的listview界面)
  5. 【Android(安卓)开发教程】保存到外部存储设备(SD卡)
  6. Android(安卓)添加动画的标签栏
  7. android完整权限
  8. android 4.4 沉浸式状态栏实现
  9. Android(安卓)网络编程 Socket Http

随机推荐

  1. 简单的通过request判断客户端设备类型
  2. java基础 注解 android中的实现
  3. Android 友盟
  4. Android获取屏幕分辨率和dpi
  5. Android之日期时间选择器使用方法
  6. mtk android 背光设置
  7. 实现调用Android手机的拍照功能
  8. Android客户端上传文件到服务器端
  9. Android 按两次back键退出 -- 效率最高版
  10. Android代码规范