博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
谷歌Volley网络框架讲解——Network及其实现类
阅读量:6364 次
发布时间:2019-06-23

本文共 5929 字,大约阅读时间需要 19 分钟。

我们看到Network接口只有一个实现类BasicNetwork,而HttpStack有两个实现类。

BasicNetwork这个类是toolbox工具箱包里的,实现了Network接口。

先来看下Network这个interface,performRequest(Request*)执行一个请求,以一个Request为参数,返回一个

NetworkResponse 。
public interface Network {    /**     * Performs the specified request.执行这个请求     * @param request Request to process//待处理的请求     * @return A {
@link NetworkResponse} with data and caching metadata; will never be null * 返回一个请求结果,不会为空 * @throws VolleyError on errors */ public NetworkResponse performRequest(Request
request) throws VolleyError;}

BasicNetwork实现了Network接口,我们来看下UML图。

再来看下它的构造函数,两个参数HttpStack和ByteArrayPool,这两个参数就是主要的成员变量。

/**     * 带一个默认大小的ByteArrayPool缓冲池     * @param httpStack HTTP stack to be used     */    public BasicNetwork(HttpStack httpStack) {        // If a pool isn't passed in, then build a small default pool that will give us a lot of        // benefit and not use too much memory.        //如果一个池没有通过,将建立一个小的默认缓存池,这样会给我们带来很大的益处,不需要耗费很多内存        this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE));    }    /**     * 主构造方法BasicNetwork(HttpStack*,ByteArrayPool*)     * @param httpStack HTTP stack to be used     * @param pool a buffer pool that improves GC performance in copy operations     */    public BasicNetwork(HttpStack httpStack, ByteArrayPool pool) {        mHttpStack = httpStack;        mPool = pool;    }

再看看哪个方法用到了mHttpStack,就是在实现Network接口的performRequest()方法,并且mHttpStack有个跟Network接口同名的方法,这才是真正执行请求的方法,也是直接传入请求返回响应。

而mPool是在entityToBytes()这个方法中用到,顾名思义这个方法就是把HttpEntity转换为bytes数据,而这个缓存池就是为便捷转换数据格式。

再详细看下最重要的方法performRequest(),代码中均以加上注释,见解有误望读者们见谅和请教。

/**     * @title performRequest执行各种Request请求并以NetworkResponse的形式返回结果     * @param Request     * @return NetworkResponse     * @throws VolleyError     * 定义:{
@link Network#performRequest(Request)} * 被调:{
@link NetworkDispatcher#run()} * */ @Override//NetworkDispatcher的run()方法中调用 public NetworkResponse performRequest(Request
request) throws VolleyError { long requestStart = SystemClock.elapsedRealtime();//开始请求时间 while (true) { HttpResponse httpResponse = null;//apache的请求结果 byte[] responseContents = null;//请求的内容 Map
responseHeaders = new HashMap
();//响应结果头部信息 try { // Gather headers. Map
headers = new HashMap
();//保存缓存数据 addCacheHeaders(headers, request.getCacheEntry());//先获取缓存数据 httpResponse = mHttpStack.performRequest(request, headers);//去调用mHttpStack的实现方法执行请求 StatusLine statusLine = httpResponse.getStatusLine();//获取http状态线 int statusCode = statusLine.getStatusCode();//获取状态码 responseHeaders = convertHeaders(httpResponse.getAllHeaders()); // Handle cache validation.//处理缓存验证 if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
//返回缓存数据 return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, request.getCacheEntry().data, responseHeaders, true); } //把HttpEntity转化为byte[]数据 responseContents = entityToBytes(httpResponse.getEntity()); // if the request is slow, log it.//如果请求很慢,就打印出来看一下 long requestLifetime = SystemClock.elapsedRealtime() - requestStart; logSlowRequests(requestLifetime, request, responseContents, statusLine);//打印 //连接正常但是返回无内容,抛出IO异常 if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_NO_CONTENT) { throw new IOException(); } 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) {
//Bad URL throw new RuntimeException("Bad URL " + request.getUrl(), e); } catch (IOException e) {
//IO异常 int statusCode = 0; NetworkResponse networkResponse = null; if (httpResponse != null) { statusCode = httpResponse.getStatusLine().getStatusCode(); } else {
//如果没有返回httpResponse,就说明没连接 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);//只有状态码为5XX才抛出服务器异常 } } else {
//网络异常 throw new NetworkError(networkResponse); } } } }

A:先是通过mHttpStack把请求执行并且获取它的响应结果,根据HttpStatus做出各种判断。

B:然后再把httpResponse的Entity转化为ByteArray,并处理各种发生的异常。

C:最后的过程是这样的:通过Volley创建一个RequestQueue请求队列,当这个队列开始运作的时候会启动NetworkDispatcher这个工作线程,而BasicNetwork的performRequest()的方法就在NetworkDispatcher线程run()方法中调用,然后通过mHttpStack的performRequest()方法获取一个networkResponse,在NetworkDispatcher线程把这个networkResponse转化为期望的数据类型,比如Response<String>,Response<Json>,Response<Bitmap>。

 

转载地址:http://niama.baihongyu.com/

你可能感兴趣的文章
计算分页
查看>>
iptables 做nat路由器脚本
查看>>
数据结构(C语言版)第三章:栈和队列
查看>>
Keepalive 之 keepalive概念介绍
查看>>
Stopping and/or Restarting an embedded Jetty in...
查看>>
Oracle存储过程中的数据集输入参数
查看>>
vsftp 配置
查看>>
VCSA中配置时间和时区,实测至6.5适用
查看>>
高并发IM系统架构优化实践
查看>>
产品经理教你玩转阿里云负载均衡SLB系列(一):快速入门--什么是负载均衡
查看>>
有关linux--进程组、会话、守护进程详解
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
monkeyrunner运行Python脚本来检查apk渠道和验证是否可以调用微信
查看>>
github获得SSH Key解决Permission denied (publickey)问题
查看>>
用java代码编写Oracle存储过程
查看>>
APACHE转发
查看>>
android-market-api
查看>>
解決 yum update錯誤:[Errno -1] Metadata file does not match checksum
查看>>
ASP.NET(C#)Excel导入Dataset的出现数据值丢失问题
查看>>