Volley的框架解读二(Http访问及处理)
2017-09-17 16:31
351 查看
先看UML图
源码解读绝招二:把握类的主要流程,大体看一下用到的类,看看方法,猜一下用法,别去抓细节。
在volley中执行网络请求的接口是Network,其实现类是BasicNetwork。
需要注意的是,将Network与HttpStack、HttpClientStack 、HurlStack进行区别。HttpStack是定义网络请求的,是使用HttpClient或者HttpURLConnection来连接网络。Network则是使用HttpStack来执行网络请求,Network是使用者。
不清楚HttpStack可以看我上一篇文章
Volley的框架解读一(Http的封装)
Network接口内定义了一个唯一的方法public NetworkResponse performRequest(Request<?> request) 其作用就是执行网络请求,并获取返回值。
Network是一个接口,volley中该接口的默认实现类是BasicNetwork。
BasicNetwork具体执行了网络请求,它有这么几个作用:
执行HttpStack网络请求,获取响应。
请求网络,如果请求失败还需要进行请求重试策略
解析响应,组装成可以被volley传递的NetworkResponse
在解析响应实体的时候,使用字节数组缓冲池技术
主要方法也就是:performRequest(),在volley中也就是使用HttpStack获取响应内容,然后根据响应码来做一些重试策略,缓存策略。
其实volley源码中,可以看到每个类基本做到了就是一个作用(单一职责),同时也通过组合的形式,添加一些新的职责,比如BasicNetwork
基本就是处理了,不同响应码有不同的处理
当然也没什么难得地方,代码注释也写的很清楚。
源码解读绝招二:把握类的主要流程,大体看一下用到的类,看看方法,猜一下用法,别去抓细节。
在volley中执行网络请求的接口是Network,其实现类是BasicNetwork。
需要注意的是,将Network与HttpStack、HttpClientStack 、HurlStack进行区别。HttpStack是定义网络请求的,是使用HttpClient或者HttpURLConnection来连接网络。Network则是使用HttpStack来执行网络请求,Network是使用者。
不清楚HttpStack可以看我上一篇文章
Volley的框架解读一(Http的封装)
Network接口内定义了一个唯一的方法public NetworkResponse performRequest(Request<?> request) 其作用就是执行网络请求,并获取返回值。
/** * * 调用HttpStack处理请求,并将结果转换为可被ResponseDelivery处理的NetworkResponse。 * 代表网络的接口,处理网络请求。 唯一的方法,用于执行特定请求 */ public interface Network { /** * @param request 执行网络请求,获取一个从网络后返回的响应 ,BasicNetwork是该接口的实现类 * @return NetworkResponse是响应数据,该数据是根据从缓存获得或从网络中获取的响应数据封装起来的 * @throws VolleyError */ public NetworkResponse performRequest(Request<?> request) throws VolleyError; }
Network是一个接口,volley中该接口的默认实现类是BasicNetwork。
BasicNetwork具体执行了网络请求,它有这么几个作用:
执行HttpStack网络请求,获取响应。
请求网络,如果请求失败还需要进行请求重试策略
解析响应,组装成可以被volley传递的NetworkResponse
在解析响应实体的时候,使用字节数组缓冲池技术
主要方法也就是:performRequest(),在volley中也就是使用HttpStack获取响应内容,然后根据响应码来做一些重试策略,缓存策略。
其实volley源码中,可以看到每个类基本做到了就是一个作用(单一职责),同时也通过组合的形式,添加一些新的职责,比如BasicNetwork
基本就是处理了,不同响应码有不同的处理
@Override public NetworkResponse performRequest(Request<?> request) throws VolleyError { long requestStart = SystemClock.elapsedRealtime(); //这里使用while(true)的含义是:保证请求重试策略的执行。 //如果网络正常返回结果 那么直接return //如果需要进行请求重试,就用到这里了,保证了可以进行请求重试 while (true) { //系统的网络请求的响应 HttpResponse httpResponse = null; //存放响应实体的字节数组 byte[] responseContents = null; //存储响应头信息的map Map<String, String> responseHeaders = new HashMap<String, String>(); try { // Gather headers. Map<String, String> headers = new HashMap<String, String>(); //从request中获取一些头的信息,新鲜度验证的tag和缓存的响应的响应时间 addCacheHeaders(headers, request.getCacheEntry()); //执行请求,获得相应 httpResponse = mHttpStack.performRequest(request, headers); //获取响应的状态行 StatusLine statusLine = httpResponse.getStatusLine(); //获取状态码 int statusCode = statusLine.getStatusCode(); //将响应的头信息转为map存储 responseHeaders = convertHeaders(httpResponse.getAllHeaders()); // Handle cache validation. 返回的状态码是304 表示可以使用缓存数据 if (statusCode == HttpStatus.SC_NOT_MODIFIED) { return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, request.getCacheEntry().data, responseHeaders, true); } // Some responses such as 204s do not have content. We must check.204(无内容)服务器成功处理了请求,但没有返回任何内容 if (httpResponse.getEntity() != null) { //响应实体不为空,使用的是响应实体的数据,获取响应的实体 转为字节数组 //这里有可能抛出IO异常,当出现异常的时候需要再下面捕获异常并进行处理,主要是完成创建可被传递的NetworkResponse responseContents = entityToBytes(httpResponse.getEntity()); } else { // Add 0 byte response as a way of honestly representing a // no-content request. responseContents = new byte[0]; } // if the request is slow, log it. long requestLifetime = SystemClock.elapsedRealtime() - requestStart; logSlowRequests(requestLifetime, request, responseContents, statusLine); if (statusCode < 200 || statusCode > 299) { throw new IOException(); } //根据httpResponse的信息,组装成可以被volley传递的networkresponse //此时while循环结束 return new NetworkResponse(statusCode, responseContents, responseHeaders, false); //如果发生超时,认证失败等错误,进行重试操作,直到成功、抛出异常(不满足重试策略等)结束 } catch (SocketTimeoutException e) { //当出现异常的时候,尝试进行请求重试 attemptRetryOnException("socket", request, new TimeoutError()); } catch (ConnectTimeoutException e) { //当出现连接异常的时候,尝试进行请求重试 attemptRetryOnException("connection", request, new TimeoutError()); } catch (MalformedURLException e) { //url不正常异常 throw new RuntimeException("Bad URL " + request.getUrl(), e); } catch (IOException e) { //当出现IO异常时,在try内读取数据体时,如果出现IO异常,那么捕获异常,继续完成创建NetworkResponse的过程 int statusCode = 0; NetworkResponse networkResponse = null; //如果响应不为空 if (httpResponse != null) { //获取返回的状态码 statusCode = httpResponse.getStatusLine().getStatusCode(); } else { //响应为空就表明 网络连接错误 throw new NoConnectionError(e); } VolleyLog.e("Unexpected response code %d for %s", statusCode, request.getUrl()); if (responseContents != null) { //根据状态码、响应的实体数、响应头信息创建可被传递的响应 networkResponse = new NetworkResponse(statusCode, responseContents, responseHeaders, false); //如果状态码是授权未通过 if (statusCode == HttpStatus.SC_UNAUTHORIZED || statusCode == HttpStatus.SC_FORBIDDEN) { //请求重试策略 attemptRetryOnException("auth", request, new AuthFailureError(networkResponse)); } else { // TODO: Only throw ServerError for 5xx status codes. throw new ServerError(networkResponse); } } else { throw new NetworkError(networkResponse); } } } }
当然也没什么难得地方,代码注释也写的很清楚。
相关文章推荐
- Volley的框架解读准备一HttpURLConnection
- Volley的框架解读一(Http的封装)
- Android 网络访问框架retrofit2,okhttp3之简单封装,kotlin源码
- Win8开发中 app的Http访问权限处理
- Android HTTP网络通信(二):Volley框架——介绍、基本用法
- Tomcat源码解读系列(三)——Tomcat对HTTP请求处理的整体流程
- Android 访问网络框架之——OkHttp框架的解析
- Volley框架的基本解读(一)
- 遭遇“HTTP 错误 500.19 无法访问请求的页面,因为该页的相关配置数据无效。”处理
- javaweb开发中异步ajax请求之DWR框架详解(通过直接访问java类实现异步请求处理)
- Volley--http框架的实例
- spring mvc框架整个执行过程,从输入http url,到action映射,再到action处理,返回jsp文件,解析jsp文件,然后渲染, 到返回给浏览器展示结果
- viewpageindicator +fragment 在网络访问中与volley框架 null问题
- 谷歌Volley网络框架讲解——HttpStack及其实现类
- Android 谷歌 开源 通信框架 VOLLEY(三)——图片加载处理
- scrapy爬虫框架安装与应用(包括post请求、递归访问http)
- 关于Xutils框架出现无法访问HttpRequestBase 找不到org.apache.http.client.methods.HttpRequestBase解决方案
- Volley—轻量级HTTP客户端网络请求框架
- Android 开源框架之 Android-async-http 源码解读
- Android仿Volley手写属于自己的万能网络访问框架