Android 學習筆記之Volley開源框架解析(四)

 

 

學習內容:java

1.NetWorkDispatcher網絡請求線程調度...android

2.NetWork網絡請求抽象類...apache

3.BasicNetWork網絡請求抽象類的具體實現...數組

4.NetWorkResponse接收網絡請求返回的響應...緩存

5.ResponseDelivery請求分配抽象類...服務器

6.ExecutorDelivery請求分配的具體實現類...網絡

 

  上一章說完了緩存請求線程調度,那麼如今就說一下網絡請求線程調度是如何來完成的,網絡請求線程調度也是有一個核心過程的,從網絡上獲取數據信息的過程, 首先從網絡請求隊列取出請求,若是請求存在,那麼對請求進行相關的處理,若是沒有請求,那麼線程進入等待狀態,取出請求以後須要先對請求是否已經被中途取 消進行相關的判斷,若是已經請求已經被中途中斷,那麼結束此次的處理過程,若是沒有取消,那麼執行請求,獲取服務器的返回數據,而後對返回的響應是夠是 304響應進行相關的判斷,若是是304響應,那麼直接也結束對請求的處理。併發

  304請求表示的是相同請求已經被服務器響應,而且返回了已經返回了相關的數據,因爲服務器的狀態是高併發的執行狀態,有可能在同一時間段對兩種或幾種相同的請求進行相關的處理,那麼對於這樣多種相同的請求,服務器只須要響應一次數據就能夠了,剩下的由ResponseDelivery去分發給全部與之相同的請求就能夠了...也就是說服務器對於同一時間段的多個相同的請求只須要響應一次...app

  若是不是304響應,那麼表示此次請求是一個新的請求,那麼咱們須要向服務器發送請求來獲取服務器的響應,最後經過是否進行緩存進行判斷以後,一個請求就能夠被分發出去了...socket

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方法以後,就完全的完成了請求——響應的結束過程...數據也就成功的從服務器經過網絡成功的發送給了客戶端...

相關文章
相關標籤/搜索