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方法之后,就彻底的完成了请求——响应的结束过程...数据也就成功的从服务器通过网络成功的发送给了客户端...



 

原文地址:https://www.cnblogs.com/RGogoing/p/4901205.html