1. 程式人生 > >Volley拓展框架——Netroid,以及與Volley的差異

Volley拓展框架——Netroid,以及與Volley的差異

轉自:http://blog.csdn.net/brian512/article/details/50499423?ref=myread

Netroid是一個基於Volley實現的Android Http庫。提供執行網路請求、快取返回結果、批量圖片載入、大檔案斷點下載的常見Http互動功能。致力於避免每個專案重複開發基礎Http功能,實現顯著地縮短開發週期的願景。

功能上的區別:

作為Volley的拓展框架,netroid增加了大檔案斷點下載,並且netroid的可定製性更強。

實現上的區別:

1. 快取的處理;

在volley中,快取的過期時間是通過 ttl 和 softTtl 控制

<code class="hljs java has-numbering">        <span class="hljs-javadoc">/** True if the entry is expired. */</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isExpired</span>() {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.ttl < System.currentTimeMillis();
        }

        <span class="hljs-javadoc">/** True if a refresh is needed from the original data source. */</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">refreshNeeded</span>() {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.softTtl < System.currentTimeMillis();
        }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>

而這兩個值的來源是HttpHeaderParser.parseCacheHeaders

<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Cache.Entry <span class="hljs-title">parseCacheHeaders</span>(NetworkResponse response) {
    <span class="hljs-keyword">long</span> now = System.currentTimeMillis();    
    <span class="hljs-keyword">long</span> serverDate = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">long</span> lastModified = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">long</span> serverExpires = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">long</span> softExpire = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">long</span> finalExpire = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">long</span> maxAge = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">long</span> staleWhileRevalidate = <span class="hljs-number">0</span>;
    boolean hasCacheControl = <span class="hljs-keyword">false</span>;
    boolean mustRevalidate = <span class="hljs-keyword">false</span>;    
    String serverEtag = <span class="hljs-keyword">null</span>;
    headerValue = headers.<span class="hljs-keyword">get</span>(<span class="hljs-string">"Date"</span>);
    <span class="hljs-keyword">if</span> (headerValue != <span class="hljs-keyword">null</span>) {
        serverDate = parseDateAsEpoch(headerValue);
    }    headerValue = headers.<span class="hljs-keyword">get</span>(<span class="hljs-string">"Cache-Control"</span>);
    <span class="hljs-keyword">if</span> (headerValue != <span class="hljs-keyword">null</span>) {
        hasCacheControl = <span class="hljs-keyword">true</span>;
        String[] tokens = headerValue.split(<span class="hljs-string">","</span>);
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < tokens.length; i++) {
            String token = tokens[i].trim();
            <span class="hljs-keyword">if</span> (token.equals(<span class="hljs-string">"no-cache"</span>) || token.equals(<span class="hljs-string">"no-store"</span>)) {
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (token.startsWith(<span class="hljs-string">"max-age="</span>)) {
                <span class="hljs-keyword">try</span> {
                    maxAge = Long.parseLong(token.substring(<span class="hljs-number">8</span>));
                } <span class="hljs-keyword">catch</span> (Exception e) {
                }
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (token.startsWith(<span class="hljs-string">"stale-while-revalidate="</span>)) {
                <span class="hljs-keyword">try</span> {
                    staleWhileRevalidate = Long.parseLong(token.substring(<span class="hljs-number">23</span>));
                } <span class="hljs-keyword">catch</span> (Exception e) {
                }
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (token.equals(<span class="hljs-string">"must-revalidate"</span>) || token.equals(<span class="hljs-string">"proxy-revalidate"</span>)) {
                mustRevalidate = <span class="hljs-keyword">true</span>;
            }
        }
    }    
    headerValue = headers.<span class="hljs-keyword">get</span>(<span class="hljs-string">"Expires"</span>);
    <span class="hljs-keyword">if</span> (headerValue != <span class="hljs-keyword">null</span>) {
        serverExpires = parseDateAsEpoch(headerValue);
    }    
    headerValue = headers.<span class="hljs-keyword">get</span>(<span class="hljs-string">"Last-Modified"</span>);
    <span class="hljs-keyword">if</span> (headerValue != <span class="hljs-keyword">null</span>) {
        lastModified = parseDateAsEpoch(headerValue);
    <span class="hljs-comment">// Cache-Control takes precedence over an Expires header, even if both exist and Expires is more restrictive.</span>
    <span class="hljs-comment">// 如果伺服器返回的header中有Cache-Control欄位,則可以按照制定的規則進行設定</span>
    <span class="hljs-keyword">if</span> (hasCacheControl) {
        softExpire = now + maxAge * <span class="hljs-number">1000</span>;
        finalExpire = mustRevalidate
                ? softExpire
                : softExpire + staleWhileRevalidate * <span class="hljs-number">1000</span>;
    } 
    <span class="hljs-comment">// 若伺服器返回的header中包含Expires和Date欄位</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (serverDate > <span class="hljs-number">0</span> && serverExpires >= serverDate) {
        <span class="hljs-comment">// Default semantic for Expire header in HTTP specification is softExpire.</span>
        softExpire = now + (serverExpires - serverDate);
        finalExpire = softExpire;
    }    
    Cache.Entry entry = <span class="hljs-keyword">new</span> Cache.Entry();
    entry.data = response.data;
    entry.etag = serverEtag;
    entry.softTtl = softExpire;
    entry.ttl = finalExpire;
    entry.serverDate = serverDate;
    entry.lastModified = lastModified;
    <span class="hljs-keyword">return</span> entry;
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li></ul>

根據上述程式碼中的中文註釋看,若伺服器返回的header中沒有Cache-Control,Expires,Date等欄位,則 ttl 和 softExpire 的值均為預設的0,從而使得快取永遠是過期的,其影響是快取不僅不能起效,反而每次網路請求都需要更新快取,最後就是拖累整體效能。

為此,netroid採用expireTime欄位替代了 ttl 和 softExpire ,每次發起請求時,需指定過期時間

<code class="hljs java has-numbering">    <span class="hljs-comment">// com.duowan.mobile.netroid.Request.java</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCacheExpireTime</span>(TimeUnit timeUnit, <span class="hljs-keyword">int</span> amount) {
        <span class="hljs-keyword">this</span>.mCacheExpireTime = System.currentTimeMillis() + timeUnit.toMillis(amount);
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">shouldCache</span>() {
        <span class="hljs-keyword">return</span> mCacheExpireTime > <span class="hljs-number">0</span>;
    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul>

從上述程式碼看出,若沒有設定過期時間時,不會產生快取

<code class="hljs java has-numbering">        <span class="hljs-javadoc">/** True if the entry is expired. */</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isExpired</span>() {
            <span class="hljs-keyword">return</span> expireTime < System.currentTimeMillis();
        }

        <span class="hljs-javadoc">/** True if a refresh is needed from the original data source. */</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">refreshNeeded</span>() {
            <span class="hljs-comment">// still unimplemented, might be use a constant like 'refreshTime'?</span>
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.expireTime < System.currentTimeMillis();
        }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>

2. 網路資料處理;

首先貼一段帶註釋的程式碼:

<code class="hljs java has-numbering">    <span class="hljs-keyword">public</span> NetworkResponse <span class="hljs-title">performRequest</span>(Request<?> request) <span class="hljs-keyword">throws</span> VolleyError {
        <span class="hljs-comment">// Determine if request had non-http perform.</span>
        <span class="hljs-comment">// 若該請求不需要訪問網路,則直接複寫perform方法。使用場景如,載入資料庫的資料,或者載入本地圖片,使用此框架可以統一處理此類耗時操作</span>
        NetworkResponse networkResponse = request.perform();
        <span class="hljs-keyword">if</span> (networkResponse != <span class="hljs-keyword">null</span>) 
            <span class="hljs-keyword">return</span> networkResponse;

        <span class="hljs-keyword">long</span> requestStart = SystemClock.elapsedRealtime();
        <span class="hljs-keyword">while</span> (<span class="hljs-keyword">true</span>) {
            <span class="hljs-comment">// If the request was cancelled already,</span>
            <span class="hljs-comment">// do not perform the network request.</span>
            <span class="hljs-keyword">if</span> (request.isCanceled()) {
                request.finish(<span class="hljs-string">"perform-discard-cancelled"</span>);
                mDelivery.postCancel(request);
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NetworkError(networkResponse);
            }

            HttpResponse httpResponse = <span class="hljs-keyword">null</span>;
            <span class="hljs-keyword">byte</span>[] responseContents = <span class="hljs-keyword">null</span>;
            <span class="hljs-keyword">try</span> {
                <span class="hljs-comment">// prepare to perform this request, normally is reset the request headers.</span>
                <span class="hljs-comment">// 此方法預設實現為空,若請求有需要預處理的話,該設計也是極好的。使用場景如,在進行大檔案斷點下載時,需要設定Range頭欄位,但是網路異常進行retry時就不太好處理range了,但是有這個方法就很簡單了</span>
                request.prepare();

                httpResponse = mHttpStack.performRequest(request);

                StatusLine statusLine = httpResponse.getStatusLine();
                <span class="hljs-keyword">int</span> statusCode = statusLine.getStatusCode();
                <span class="hljs-keyword">if</span> (statusCode < <span class="hljs-number">200</span> || statusCode > <span class="hljs-number">299</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IOException();

                <span class="hljs-comment">// 此方法的預設實現為volley的實現方法,但是可以複寫該方法。volley的實現方式是直接把請求到的資料轉為byte[],此方式會限制請求的資料量不能太大,否則會OOM。</span>
                <span class="hljs-comment">// 若下載大檔案時,就得複寫這個方法,將網路請求的資料流讀寫到檔案,而不是記憶體</span>
                responseContents = request.handleResponse(httpResponse, mDelivery);

                <span class="hljs-comment">// if the request is slow, log it.</span>
                <span class="hljs-keyword">long</span> requestLifetime = SystemClock.elapsedRealtime() - requestStart;
                logSlowRequests(requestLifetime, request, responseContents, statusLine);

                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> NetworkResponse(statusCode, responseContents, parseCharset(httpResponse));
            } <span class="hljs-keyword">catch</span> (SocketTimeoutException e) {
                attemptRetryOnException(<span class="hljs-string">"socket"</span>, request, <span class="hljs-keyword">new</span> TimeoutError());
            } <span class="hljs-keyword">catch</span> (ConnectTimeoutException e) {
                attemptRetryOnException(<span class="hljs-string">"connection"</span>, request, <span class="hljs-keyword">new</span> TimeoutError());
            } <span class="hljs-keyword">catch</span> (MalformedURLException e) {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(<span class="hljs-string">"Bad URL "</span> + request.getUrl(), e);
            } <span class="hljs-keyword">catch</span> (IOException e) {
                。。。
            }
        }
    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li></ul>

3. 資料請求過程回撥;

在volley的實現中,是通過ExecutorDelivery將資料請求的結果回撥給呼叫者。

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ResponseDelivery</span> {</span>
    <span class="hljs-javadoc">/**
     * Parses a response from the network or cache and delivers it.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">postResponse</span>(Request<?> request, Response<?> response);

    <span class="hljs-javadoc">/**
     * Parses a response from the network or cache and delivers it. The provided
     * Runnable will be executed after delivery.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">postResponse</span>(Request<?> request, Response<?> response, Runnable runnable);

    <span class="hljs-javadoc">/**
     * Posts an error for the given request.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">postError</span>(Request<?> request, VolleyError error);
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul>

netroid在此基礎上增加了一些回撥:

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Delivery</span> {</span>

    <span class="hljs-javadoc">/** Posts request finished callback for the given request. */</span>
    <span class="hljs-keyword">void</span> postFinish(Request<?> request);

    <span class="hljs-javadoc">/** Parses a response from the network or cache and delivers it. */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">postResponse</span>(Request<?> request, Response<?> response);

    <span class="hljs-javadoc">/**
     * Parses a response from the network or cache and delivers it. The provided
     * Runnable will be executed after delivery.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">postResponse</span>(Request<?> request, Response<?> response, Runnable runnable);

    <span class="hljs-javadoc">/** Posts an error for the given request. */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">postError</span>(Request<?> request, VolleyError error);

    <span class="hljs-javadoc">/** Posts a cancel callback for the given request. */</span>
    <span class="hljs-keyword">void</span> postCancel(Request<?> request);

    <span class="hljs-javadoc">/** Posts starting execute callback for the given request. */</span>
    <span class="hljs-keyword">void</span> postPreExecute(Request<?> request);

    <span class="hljs-javadoc">/** Posts cache used callback for the given request. */</span>
    <span class="hljs-keyword">void</span> postUsedCache(Request<?> request);

    <span class="hljs-javadoc">/** Posts networking callback for the given request. */</span>
    <span class="hljs-keyword">void</span> postNetworking(Request<?> request);

    <span class="hljs-javadoc">/** Posts request retry callback for the given request. */</span>
    <span class="hljs-keyword">void</span> postRetry(Request<?> request);

    <span class="hljs-javadoc">/** Posts file download progress stat. */</span>
    <span class="hljs-keyword">void</span> postDownloadProgress(Request<?> request, <span class="hljs-keyword">long</span> fileSize, <span class="hljs-keyword">long</span> downloadedSize);
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li></ul>

可以看出,這些回撥基本覆蓋了請求過程中的關鍵點,主要是有postDownloadProgress方法,進行回撥檔案下載進度。

<code class="hljs avrasm has-numbering">                // <span class="hljs-keyword">com</span><span class="hljs-preprocessor">.duowan</span><span class="hljs-preprocessor">.mobile</span><span class="hljs-preprocessor">.netroid</span><span class="hljs-preprocessor">.NetworkDispatcher</span><span class="hljs-preprocessor">.java</span>
                request<span class="hljs-preprocessor">.addMarker</span>(<span class="hljs-string">"network-queue-take"</span>)<span class="hljs-comment">;</span>
                mDelivery<span class="hljs-preprocessor">.postPreExecute</span>(request)<span class="hljs-comment">;</span>

                // If the request was cancelled already,
                // do not perform the network request.
                if (request<span class="hljs-preprocessor">.isCanceled</span>()) {
                    request<span class="hljs-preprocessor">.finish</span>(<span class="hljs-string">"network-discard-cancelled"</span>)<span class="hljs-comment">;</span>
                    mDelivery<span class="hljs-preprocessor">.postCancel</span>(request)<span class="hljs-comment">;</span>
                    mDelivery<span class="hljs-preprocessor">.postFinish</span>(request)<span class="hljs-comment">;</span>
                    continue<span class="hljs-comment">;</span>
                }

                // Perform the network request.
                NetworkResponse networkResponse = mNetwork<span class="hljs-preprocessor">.performRequest</span>(request)<span class="hljs-comment">;</span>
                request<span class="hljs-preprocessor">.addMarker</span>(<span class="hljs-string">"network-http-complete"</span>)<span class="hljs-comment">;</span>

                // Parse the response here on the worker thread.
                Response<?> response = request<span class="hljs-preprocessor">.parseNetworkResponse</span>(networkResponse)<span class="hljs-comment">;</span>
                request<span class="hljs-preprocessor">.addMarker</span>(<span class="hljs-string">"network-parse-complete"</span>)<span class="hljs-comment">;</span>

                // Write to cache if applicable.
                if (mCache != null && request<span class="hljs-preprocessor">.shouldCache</span>() && response<span class="hljs-preprocessor">.cacheEntry</span> != null) {
                    response<span class="hljs-preprocessor">.cacheEntry</span><span class="hljs-preprocessor">.expireTime</span> = request<span class="hljs-preprocessor">.getCacheExpireTime</span>()<span class="hljs-comment">;</span>
                    mCache<span class="hljs-preprocessor">.putEntry</span>(request<span class="hljs-preprocessor">.getCacheKey</span>(), response<span class="hljs-preprocessor">.cacheEntry</span>)<span class="hljs-comment">;</span>
                    request<span class="hljs-preprocessor">.addMarker</span>(<span class="hljs-string">"network-cache-written"</span>)<span class="hljs-comment">;</span>
                }

                // Post the response back.
                request<span class="hljs-preprocessor">.markDelivered</span>()<span class="hljs-comment">;</span>
                mDelivery<span class="hljs-preprocessor">.postResponse</span>(request, response)<span class="hljs-comment">;</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li></ul><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li></ul>

從上述程式碼看出,回撥確實很多,若在這些回撥中新增太多操作的話,肯定會影響資料請求的速度。

總的來說,netroid相對volley的改進還是不錯的,這也是這兩天看程式碼的總結,如有遺漏,後面再補充!