zoukankan      html  css  js  c++  java
  • 谷歌Volley网络框架讲解——Network及其实现类

    我们看到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<String, String> responseHeaders = new HashMap<String, String>();//响应结果头部信息
                try {
                    // Gather headers.
                    Map<String, String> headers = new HashMap<String, String>();//保存缓存数据
                    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>。

  • 相关阅读:
    17岁韩寒在CCTV《对话》舌战群吊的视频
    在线LaTex编辑器
    PowerShell 点滴记录
    程序阅读理解题目(高中语文版,附答案)
    jQuery Validate 应用
    ASP.net MVC 向子视图传递数据
    分库分表(sharding)后主键全局唯一性的解决方案
    Ajax局部刷新例子
    限制 Flash 在指定域名/网址中播放 (Flash 防盗链)
    javascript实现二级联动下拉框
  • 原文地址:https://www.cnblogs.com/bvin/p/3286908.html
Copyright © 2011-2022 走看看