• Android 学习笔记之Volley开源框架解析(四)


    学习内容:

    1.NetWorkDispatcher网络请求线程调度...

    2.NetWork网络请求抽象类...

    3.BasicNetWork网络请求抽象类的具体实现...

    4.NetWorkResponse接收网络请求返回的响应...

    5.ResponseDelivery请求分配抽象类...

    6.ExecutorDelivery请求分配的具体实现类...

      上一章说完了缓存请求线程调度,那么现在就说一下网络请求线程调度是如何来完成的,网络请求线程调度也是有一个核心过程的,从网络上获取数据信息的过程, 首先从网络请求队列取出请求,如果请求存在,那么对请求进行相关的处理,如果没有请求,那么线程进入等待状态,取出请求之后需要先对请求是否已经被中途取 消进行相关的判断,如果已经请求已经被中途中断,那么结束这次的处理过程,如果没有取消,那么执行请求,获取服务器的返回数据,然后对返回的响应是够是 304响应进行相关的判断,如果是304响应,那么直接也结束对请求的处理。

      304请求表示的是相同请求已经被服务器响应,并且返回了已经返回了相关的数据,由于服务器的状态是高并发的执行状态,有可能在同一时间段对两种或几种相同的请求进行相关的处理,那么对于这样多种相同的请求,服务器只需要响应一次数据就可以了,剩下的由ResponseDelivery去分发给所有与之相同的请求就可以了...也就是说服务器对于同一时间段的多个相同的请求只需要响应一次...

      如果不是304响应,那么表示这次请求是一个新的请求,那么我们需要向服务器发送请求来获取服务器的响应,最后通过是否进行缓存进行判断之后,一个请求就可以被分发出去了...

    1.NetWorkDispatcher.java

      1.1 变量的定义

     private final BlockingQueue<Request> mQueue;  //请求队列...
        /** The network interface for processing requests. */
        private final Network mNetwork;  //网络请求对象,用于执行网络请求工作
        /** The cache to write to. */
        private final Cache mCache;  //缓存对象,用于缓存数据
        /** For posting responses and errors. */
        private final ResponseDelivery mDelivery;  //用于分发请求...
        /** Used for telling us to die. */
        private volatile boolean mQuit = false; //  用于关闭线程...

      1.2 NetWorkDispatcher构造函数...

      网络请求线程调度对象的初始化过程...构造函数比较简单,没什么说的...

     public NetworkDispatcher(BlockingQueue<Request> queue,
                Network network, Cache cache,
                ResponseDelivery delivery) {
            mQueue = queue;
            mNetwork = network;
            mCache = cache;
            mDelivery = delivery;
        }

      1.3 public void run(){}

      run()方法,线程中最重要的方法,必须要继承的...整个方式就如同刚开始介绍的一样,从请求队列中取出请求,然后判断请求是否被中断,中断就结束处理,没有中断就发送请求,然后对服务器是否已经对这次请求返回了响应数据,如果服务器已经响应了与之相同的请求,那么就停止对这次请求的处理,由分发响应函数去处理,如果是一个新的请求,那么需要定义一个请求对象,然后发送...最后获取到服务器响应后,对响应进行分发...

     @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //设置线程优先级...
            Request request;
            while (true) {
                try {
                    // Take a request from the queue.
                    request = mQueue.take(); //取出请求...
                } catch (InterruptedException e) {
                    // We may have been interrupted because it was time to quit.
                    if (mQuit) {
                        return;
                    }
                    continue;
                }
    
                try {
                    request.addMarker("network-queue-take");//添加标识符..
    
                    // If the request was cancelled already, do not perform the
                    // network request.
                    if (request.isCanceled()) { //如果请求被中途取消...
                        request.finish("network-discard-cancelled"); 添加标识符...
                        continue;
                    }
    
                    // Tag the request (if API >= 14)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { //如果API>=10,那么为请求设置标签...
                        TrafficStats.setThreadStatsTag(request.getTrafficStatsTag());
                    }
    
                    // Perform the network request.
                    NetworkResponse networkResponse = mNetwork.performRequest(request); //发送请求获取服务器的响应...
                    request.addMarker("network-http-complete");
    
                    // If the server returned 304 AND we delivered a response already,
                    // we're done -- don't deliver a second identical response.
                    if (networkResponse.notModified && request.hasHadResponseDelivered()) { //如果这个请求是没有改变..说白了就是请求如果是相同的...那么服务器就返回一次响应...其他的通过Delivery去分发就行了...
                        request.finish("not-modified");
                        continue;
                    }
    
                    // Parse the response here on the worker thread.
                    Response<?> response = request.parseNetworkResponse(networkResponse);//如果是一个新的请求,那么就需要新建一个请求对象...
                    request.addMarker("network-parse-complete");
    
                    // Write to cache if applicable.
                    // TODO: Only update cache metadata instead of entire record for 304s.
                    //如果请求允许被缓存,并且响应的数据不为空...那么将这次请求放入到缓存中..
                    if (request.shouldCache() && response.cacheEntry != null) {
                        mCache.put(request.getCacheKey(), response.cacheEntry); //放入的操作...
                        request.addMarker("network-cache-written");
                    }
    
                    // Post the response back.
                    request.markDelivered();   //确认请求要被分发...
                    mDelivery.postResponse(request, response); 发送请求...
                } catch (VolleyError volleyError) {
                    parseAndDeliverNetworkError(request, volleyError);
                } catch (Exception e) { //如果出现了错误,那么把错误发送...
                    VolleyLog.e(e, "Unhandled exception %s", e.toString());
                    mDelivery.postError(request, new VolleyError(e));
                }
            }
        }
        //一个错误处理函数,当发生解析请求或者是分发请求时出现错误时进行调用...
        private void parseAndDeliverNetworkError(Request<?> request, VolleyError error) {
            error = request.parseNetworkError(error);
            mDelivery.postError(request, error);
        }

       上面涉及到了执行请求...以及分发服务器响应,但是是如何实现的呢?我们先看如何去执行一个请求...

    2.NetWork.java

      NetWork.java是一个抽象的接口...对外提供一个执行请求方法的接口,方便其他类去实现...

    package com.android.volley;
    
    /**
     * An interface for performing requests.
     */
    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;
    }

    3.BasicNetWork.java

      BasicNetWork是实现NetWork的具体抽象类,是如何执行请求的一个具体过程,其中内部也封装了一些其他方法...

      3.1 变量的定义

      这几个变量的定义相对比较抽象,但是会在下面细说...

       protected static final boolean DEBUG = VolleyLog.DEBUG; //用于Volley内部调试..
    
        private static int SLOW_REQUEST_THRESHOLD_MS = 3000;//对于缓慢的请求定义了一个请求时间...
    
        private static int DEFAULT_POOL_SIZE = 4096; //Int值,用于以后的获取网络数据...
    
        protected final HttpStack mHttpStack;  //Http请求栈...
    
        protected final ByteArrayPool mPool; //ByteArrayPool对象...

      3.2 public BasicNetWork(){}

      构造函数...构造函数构造了一个保存Http请求栈,以及一个获取网络数据对象...

     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)); //调用下面函数..
        }
    
        /**
         * @param httpStack HTTP stack to be used
         * @param pool a buffer pool that improves GC performance in copy operations
         */
        //建立一个BasicNetWork对象,这个对象保存了一个请求栈区,另一个参数用于获取数据而建立的对象...
        public BasicNetwork(HttpStack httpStack, ByteArrayPool pool) {
            mHttpStack = httpStack;
            mPool = pool;
        }

      3.3  public NetworkResponse performRequest(Request<?> request) throws VolleyError {}

      至关重要的方法,用于执行请求,这里我们也可以看到,请求传递的参数并没有写死,而是使用了泛型的方式形成了良好的扩展,也即是说传递过来的请求是什么类型,那么就执行什么类型的请求...

     @Override
        public NetworkResponse performRequest(Request<?> request) throws VolleyError {
            long requestStart = SystemClock.elapsedRealtime(); //获取请求开始的时间,用于调试...
            while (true) {  
                HttpResponse httpResponse = null; //请求响应对象...
                byte[] responseContents = null; //请求内容对象...
                Map<String, String> responseHeaders = new HashMap<String, String>(); //map集合,用于保存数据报的Header中的数据..
                try {
                    // Gather headers.
                    Map<String, String> headers = new HashMap<String, String>(); //用于保存缓存下来的Header...缓存的Header一般包含服务响应的整体时间,缓存新鲜度验证等属性值...
                    addCacheHeaders(headers, request.getCacheEntry()); //添加请求头部的过程...
                    httpResponse = mHttpStack.performRequest(request, headers);//执行请求,获取响应..
                    StatusLine statusLine = httpResponse.getStatusLine();//获取响应状态...
                    int statusCode = statusLine.getStatusCode();//获取状态码..
    
                    responseHeaders = convertHeaders(httpResponse.getAllHeaders());//获取响应后的Header中的所有数据...
                    // Handle cache validation.
                   //对304响应的一个判断过程,如果是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.
                    if (httpResponse.getEntity() != null) {//判断响应是否是204判断,由于204响应时不返回数据信息的...因此需要判断...
                      responseContents = entityToBytes(httpResponse.getEntity()); //如果存在内容,那么通过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 != HttpStatus.SC_OK && statusCode != HttpStatus.SC_NO_CONTENT) {
                        throw new IOException(); //如果请求状态出现错误,那么抛出异常...
                    }
                    return new NetworkResponse(statusCode, responseContents, responseHeaders, false); //如果请求不是304请求,并且上面异常情况也没有发生,那么返回新的请求中的内容+头部以及状态码...
                } catch (SocketTimeoutException e) {
                    attemptRetryOnException("socket", request, new TimeoutError()); //套接字异常..
                } catch (ConnectTimeoutException e) {
                    attemptRetryOnException("connection", request, new TimeoutError());//连接超时异常...
                } catch (MalformedURLException e) {
                    throw new RuntimeException("Bad URL " + request.getUrl(), e);//url异常...
                } catch (IOException e) {//IO异常的处理...
                    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);
                    }
                }
            }
        }    

      这个函数涉及了其他几个函数...

      3.4 private void logSlowRequests(long requestLifetime, Request<?> request,byte[] responseContents, StatusLine statusLine) {}

      记录一个请求——响应的时间超出了预先设置的缓慢请求时间,那么需要进行记录...记录响应码,响应内容等等函数比较的简单...

     private void logSlowRequests(long requestLifetime, Request<?> request,
                byte[] responseContents, StatusLine statusLine) {
            if (DEBUG || requestLifetime > SLOW_REQUEST_THRESHOLD_MS) {
                VolleyLog.d("HTTP response for request=<%s> [lifetime=%d], [size=%s], " +
                        "[rc=%d], [retryCount=%s]", request, requestLifetime,
                        responseContents != null ? responseContents.length : "null",
                        statusLine.getStatusCode(), request.getRetryPolicy().getCurrentRetryCount());
            }

      3.5  private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) {}

      添加请求的请求头部,从缓存当中获取头部信息添加到这次请求...

     private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) {
            // If there's no cache entry, we're done.
            if (entry == null) { //缓存数据为空...直接return
                return;
            }
    
            if (entry.etag != null) {
                headers.put("If-None-Match", entry.etag); //返回新鲜度验证标志..
            }
    
            if (entry.serverDate > 0) {
                Date refTime = new Date(entry.serverDate); //返回请求——响应的时间...
                headers.put("If-Modified-Since", DateUtils.formatDate(refTime));
            }
        }

       3.6  private static void attemptRetryOnException(String logPrefix, Request<?> request,VolleyError exception) throws VolleyError {}

       尝试重试策略方法...如果请求发生了异常...

    private static void attemptRetryOnException(String logPrefix, Request<?> request,
                VolleyError exception) throws VolleyError {
            RetryPolicy retryPolicy = request.getRetryPolicy(); //获取请求的重试策略...
            int oldTimeout = request.getTimeoutMs();
    
            try {
                retryPolicy.retry(exception); //重试方式执行...
            } catch (VolleyError e) {
                request.addMarker(
                        String.format("%s-timeout-giveup [timeout=%s]", logPrefix, oldTimeout));
                throw e;
            }
            request.addMarker(String.format("%s-retry [timeout=%s]", logPrefix, oldTimeout));
        }

      3.7  private static Map<String, String> convertHeaders(Header[] headers) {}

     上面涉及到了当响应返回的时候需要获取响应数据报的Header,将所有的Header数据获取并保存...以键值对的形式保存在map集合当中...最后传递给responseHeaders集合...

    private static Map<String, String> convertHeaders(Header[] headers) {
            Map<String, String> result = new HashMap<String, String>();
            for (int i = 0; i < headers.length; i++) {
                result.put(headers[i].getName(), headers[i].getValue());
            }
            return result;
        }

     3.8   private byte[] entityToBytes(HttpEntity entity) throws IOException, ServerError {}

     当Http请求响应成功时,我们需要从HttpEntity中获取返回的内容数据...数据的获取调用此函数..这个函数采用了PoolingArrayByteOutputStream()流..这个流采用了字节回收机制,可以减少内存的分配和回收...我们先知道就行...后面还会具体说明...

     private byte[] entityToBytes(HttpEntity entity) throws IOException, ServerError {
            PoolingByteArrayOutputStream bytes =
                    new PoolingByteArrayOutputStream(mPool, (int) entity.getContentLength()); //新建一个流对象..
            byte[] buffer = null; //缓冲字节..
            try {
                InputStream in = entity.getContent();//将Entity中保存的内容封装成流...
                if (in == null) {
                    throw new ServerError();
                }
                buffer = mPool.getBuf(1024); //缓冲流分配...首先new一个缓冲字节数组...
                int count;
                while ((count = in.read(buffer)) != -1) {
                    bytes.write(buffer, 0, count); //写入数据...
                }
                return bytes.toByteArray();//返回数据..
            } finally {
                try {
                    // Close the InputStream and release the resources by "consuming the content".
                    entity.consumeContent();
                } catch (IOException e) {
                    // This can happen if there was an exception above that left the entity in
                    // an invalid state.
                    VolleyLog.v("Error occured when calling consumingContent");
                }
                mPool.returnBuf(buffer);
                bytes.close();
            }
        }

      这样总体就完成了请求之后响应数据的获取,也就是数据报的Header+Body的数据被保存了起来...那么完成了数据的获取,就需要响应数据的分发了...分发到请求才是请求——响应的一个最终完成过程...

    4.NetWorkResponse.java

      那么响应的传递就需要通过NetWorkResponse来进行传递,无论是从网络上获取的请求数据,还是从缓存当中获取的请求数据,都会被封装成NetWorkResponse,然后传递给相应请求中的parseNetWorkResponse方法,在进行下一步的处理...

    package com.android.volley;
    
    import org.apache.http.HttpStatus;
    
    import java.util.Collections;
    import java.util.Map;
    
    /**
     * Data and headers returned from {@link Network#performRequest(Request)}.
     */
    public class NetworkResponse {
       //对服务器的响应进行一个彻底封装...
        public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,
                boolean notModified) {
            this.statusCode = statusCode;
            this.data = data;
            this.headers = headers;
            this.notModified = notModified;
        }
        //构造函数..用来调用第一个构造函数,传递过来的响应只包含数据部分...
        public NetworkResponse(byte[] data) {
            this(HttpStatus.SC_OK, data, Collections.<String, String>emptyMap(), false);
        }
        //第二个构造函数,通过响应的数据和相关头部来调用第一个构造函数...
        public NetworkResponse(byte[] data, Map<String, String> headers) {
            this(HttpStatus.SC_OK, data, headers, false);
        }
    
        /** The HTTP status code. */
        public final int statusCode; //响应状态码...
    
        /** Raw data from this response. */
        public final byte[] data;  //响应数据...
    
        /** Response headers. */
        public final Map<String, String> headers; //以键值对的形式保存首部..
    
        /** True if the server returned a 304 (Not Modified). */
        public final boolean notModified; //304响应的判断...
    }

      NetWorkResponse只是对服务器的响应的一个进一步封装,以参数的形式传递到Request.parseNetWorkResponse()方法...如果中间并么有出现什么异常情况,那么最后相应实现了Request.parseNetWorkResponse类会调用Response.success方法,将这次请求进行最后的封装,封装成Response<T>的形式,请求是什么类型,T就是什么类型...

    5.Response.java

    package com.android.volley;
    
    public class Response<T> {
    
        /** Callback interface for delivering parsed responses. */
        public interface Listener<T> {
            /** Called when a response is received. */
            public void onResponse(T response);  //当一个请求——相应成功后的监听...
        }
    
        /** Callback interface for delivering error responses. */
        public interface ErrorListener {
            /**
             * Callback method that an error has been occurred with the
             * provided error code and optional user-readable message.
             */
            public void onErrorResponse(VolleyError error); //当请求出现了错误时,需要监听错误..
        }
    
        /** Returns a successful response containing the parsed result. */
        public static <T> Response<T> success(T result, Cache.Entry cacheEntry) {
            return new Response<T>(result, cacheEntry); //success方法,当请求被解析成功时调用的方法...
        }
    
        /**
         * Returns a failed response containing the given error code and an optional
         * localized message displayed to the user.
         */
        public static <T> Response<T> error(VolleyError error) {
            return new Response<T>(error); //如果解析请求时失败需要封装错误...
        }
    
        /** Parsed response, or null in the case of error. */
        public final T result; //响应返回的结果..
    
        /** Cache metadata for this response, or null in the case of error. */
        public final Cache.Entry cacheEntry; //缓存...
    
        /** Detailed error information if <code>errorCode != OK</code>. */
        public final VolleyError error; //一个错误对象...记录错误的生成...
    
        /** True if this response was a soft-expired one and a second one MAY be coming. */
        public boolean intermediate = false; //判断一个请求是否失效...
    
        /**
         * Returns whether this response is considered successful.
         */
        public boolean isSuccess() {
            return error == null; //如果成功就没有错误传递...
        }
    
    
        private Response(T result, Cache.Entry cacheEntry) { //对成功时封装的构造函数...
            this.result = result;
            this.cacheEntry = cacheEntry;
            this.error = null;
        }
    
        private Response(VolleyError error) {/失败时封装的构造函数...
            this.result = null;
            this.cacheEntry = null;
            this.error = error;
        }
    }

      当响应被封装成Response之后,就需要向客户端发送响应了,通过postResponse方法进行发送,如果一个响应成功,我们需要发送响应,但是如果中途出现了失败,那么我们需要把错误发送,需要让客户端清楚到底是发生了什么错误,这样在错误发生时提示用户到底应该怎样进行操作...

    6.ResponseDelivery.java

      解析响应之后的发送类,只是一个抽象的接口,我们可以人为去重写如何发送响应...而系统默认则采用线程池的方式对响应进行发送...

    package com.android.volley;
    
    public interface ResponseDelivery {
        /**
         * Parses a response from the network or cache and delivers it.
         */
        public void postResponse(Request<?> request, Response<?> response);  //对响应进行发送...
    
        /**
         * Parses a response from the network or cache and delivers it. The provided
         * Runnable will be executed after delivery.
         */
        public void postResponse(Request<?> request, Response<?> response, Runnable runnable); //对响应发送,同时开启一个线程去执行其他事情...线程在这个方法结束后执行...
    
        /**
         * Posts an error for the given request.
         */
        public void postError(Request<?> request, VolleyError error); //发送错误信息...
    }

    7.ExecutorDelivery.java

      发送请求或者是错误的具体实现类,采用线程池的方式对响应进行发送...无论是服务器响应正确还是错误,我们都需要对其进行封装发送给客户端,让客户端去清楚服务器到底返回了什么东西...

    package com.android.volley;
    
    import android.os.Handler;
    
    import java.util.concurrent.Executor;
    
    public class ExecutorDelivery implements ResponseDelivery {
        /** Used for posting responses, typically to the main thread. */
        private final Executor mResponsePoster; //定义一个线程池...
    
        //定义了一个Response的传输接口...
        public ExecutorDelivery(final Handler handler) {
            // Make an Executor that just wraps the handler.
            mResponsePoster = new Executor() {
                @Override
                public void execute(Runnable command) {
                    handler.post(command);
                }
            };
        }
    
        //构造函数,定义了一个线程池...
        public ExecutorDelivery(Executor executor) {
            mResponsePoster = executor;
        }
        //发送请求的抽象方法的实现...
        @Override
        public void postResponse(Request<?> request, Response<?> response) {
            postResponse(request, response, null);
        }
        /*最后都是通过调用此方法来发送请求,因为poseResponse的方法有两种
         * 一种是public void postResponse(Request<?> request, Response<?> response);
         * 另一种是 public void postResponse(Request<?> request, Response<?> response, Runnable runnable);
         *这两个方法上面已经说过,就是一个带有一个附加线程,一个没有而已...
         *但最终都需要调用这个方法...
         */
        @Override
        public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
            request.markDelivered(); //表示可以发送请求...
            request.addMarker("post-response");
            mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable)); //用线程封装好Response..通过线程池的方式去管理这些线程...从这一步开始run()方法已经被调用了...
        }
    
        //如果出现了错误,那么将错误封装,同时也要发送给请求的客户端...
        @Override
        public void postError(Request<?> request, VolleyError error) {
            request.addMarker("post-error");
            Response<?> response = Response.error(error); //封装错误..
            mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null)); //发送错误...
        }
    
        @SuppressWarnings("rawtypes")
        private class ResponseDeliveryRunnable implements Runnable {
            private final Request mRequest; //请求
            private final Response mResponse; //响应
            private final Runnable mRunnable; //其他线程...
            //构造函数非常的简单..对三者的一个封装过程...
            public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
                mRequest = request;
                mResponse = response;
                mRunnable = runnable;
            }
            //run方法...
            @SuppressWarnings("unchecked")
            @Override
            public void run() {
                // If this request has canceled, finish it and don't deliver.
                if (mRequest.isCanceled()) { //如果请求被中断,那么就不需要发送响应了...
                    mRequest.finish("canceled-at-delivery");
                    return;
                }
    
                // Deliver a normal response or error, depending.
                if (mResponse.isSuccess()) { //如果服务器响应成功,中途没有错误的发生,,,
                    mRequest.deliverResponse(mResponse.result);//将服务器返回的结果发送给客户端...这是最后的关键地方...
                } else {
                    mRequest.deliverError(mResponse.error);//如果其中出现了失败,需要把错误发送...
                }
    
                // If this is an intermediate response, add a marker, otherwise we're done
                // and the request can be finished.
                //这里不知道该如何理解...翻译成中间响应...
                if (mResponse.intermediate) { 
                    mRequest.addMarker("intermediate-response"); //如果是需要进行调试过程...
                } else {
                    mRequest.finish("done");//如果不是表示这次请求结束...
                }
    
                // If we have been provided a post-delivery runnable, run it.
                if (mRunnable != null) { //如果附加线程不是空,那么就启动附加线程..
                    mRunnable.run();
                }
           }
        }
    }

      我们可以看到,最后服务器的响应被封装之后,通过mRequest.deliveryResponse或者是mRequest.deliveryerror进行发送...而这两个方法就会在相应类型的请其中得到重写...因为所有的其他请求都是继承Request类的...Request类中只是一个抽象的方法,具体的实现在那些实际实现了Request的类中...而每一个实现类中都会去调用mListener.onResponse(response)方法,这里只表示请求成功时调用的方法...

    abstract protected void deliverResponse(T response);
    public interface Listener<T> {
            /** Called when a response is received. */
            public void onResponse(T response);
        }

      这样在客户端重写OnResponse方法之后,就彻底的完成了请求——响应的结束过程...数据也就成功的从服务器通过网络成功的发送给了客户端...



     

  • 相关阅读:
    CentOS中安装Nginx
    SSM框架中Mybatis的分页插件PageHelper分页失效的原因
    linux相关设置
    windows下安装ElasticSearch的Head插件
    git学习
    消息队列介绍和SpringBoot2.x整合RockketMQ、ActiveMQ 9节课
    C# if语句
    C# switch语句
    C# for语句
    C# foreach语句
  • 原文地址:https://www.cnblogs.com/RGogoing/p/4901205.html
Copyright © 2020-2023  润新知