1. 程式人生 > >volley原始碼解析(七)--最終目的之Response

volley原始碼解析(七)--最終目的之Response

在上篇文章中,我們最終通過網路,獲取到了HttpResponse物件

HttpResponse是android包裡面的一個類,然後為了更高的擴充套件性,我們在BasicNetwork類裡面看到,Volley將其包裝成一個Volley自己的物件NetworkResponse

另外,在BasicNetwork類中我們也注意到,對HttpResponse包裝成NetworkResponse的過程中,使用HttpResponse的Inputstream,將資料儲存在一個byte[]陣列中。

BasicNetwork程式碼片段:

 // Some responses such as 204s do not have content.  We must check.  
                if (httpResponse.getEntity() != null) {//返回響應主體  
                  responseContents = entityToBytes(httpResponse.getEntity());//將主體轉換byte[]形式  
                } else {//沒有返回內容  
                  // Add 0 byte response as a way of honestly representing a  
                  // no-content request.  
                  responseContents = new byte[0];  
                }  
這樣可能造成的一個問題,就是記憶體溢位,這也是Volley之所以不能用來下載大檔案的原因,因為byte[]是儲存在記憶體中的。

好了,下面讓我們來看NetworkResponse的原始碼

     /** 
     * The HTTP status code.
     * http狀態碼 
     */
    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).
     * 網頁是否修改.304 
     */
    public final boolean notModified;

    /** 
     * Network roundtrip time in milliseconds.
     * 響應時間 
     */
    public final long networkTimeMs;

/**
     * Creates a new network response.
     * @param statusCode the HTTP status code
     * @param data Response body
     * @param headers Headers returned with this response, or null for none
     * @param notModified True if the server returned a 304 and the data was already in cache
     * @param networkTimeMs Round-trip network time to receive network response
     */
    public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,
            boolean notModified, long networkTimeMs) {
        this.statusCode = statusCode;
        this.data = data;
        this.headers = headers;
        this.notModified = notModified;
        this.networkTimeMs = networkTimeMs;
    }

本質上沒有什麼特別的,只是將HttpResponse的內容,簡單地轉移到NetworkResponse中

接下來,在響應分發過程中,request負責把NetworkResponse又包裝成Response<T>物件

NetworkDispatcher程式碼片段:

// Parse the response here on the worker thread. 解析網路響應到本地
                Response<?> response = request.parseNetworkResponse(networkResponse);
至於怎麼解析,不同的request應該有自己的實現。

可能看到這裡大家有些迷糊,原因是我們找回了之前類的一些程式碼

在前面的解析中,我們總是忽略這些片段,預設為全都是Response,因為在前面的過程中,理解Response之間的不同會給我們理解核心程式碼帶來困擾,所以我們都跳過了。

現在原始碼解析接近尾聲,我們再回頭看各種各樣的Response就豁然開朗了。

httpStack獲得的是HttpResponse,由於HttpResponse是android的內建類,我們使用起來非常不靈活(因為我們希望response都是一樣的,無論是從快取中取的還是網路請求的)

根據上述原因,我們有了NetworkResponse,這個代表網路請求相應,這是Volley的自定義類,這樣我們使用起來就靈活了(理論上快取也應該有一個CacheResponse,然而Volley沒有這樣設計)。更加重要的一點是NetworkResponse中的byte[]陣列儲存了網路資料(前面說過,這是造成記憶體溢位的原因)

最後,為了統一所有的Response,我們將NetworkResponse(理論上還有一個CacheResponse)又封裝成了了Response<T>

OK,Volley解析基本到這裡就結束了。接下來的文章,將會帶大家看一下Volley最後的一部分小花絮,關於圖片載入的部分。

另外,我還會根據自己的理解,帶大家來改造Volley,使之有更多更完善的功能。