转自:http://blog.csdn.net/brian512/article/details/50499423?ref=myread
Netroid是一个基于Volley实现的Android Http库。提供执行网络请求、缓存返回结果、批量图片加载、大文件断点下载的常见Http交互功能。致力于避免每个项目重复开发基础Http功能,实现显著地缩短开发周期的愿景。
作为Volley的拓展框架,netroid增加了大文件断点下载,并且netroid的可定制性更强。
在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>
首先贴一段带注释的代码:
<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>
在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的改进还是不错的,这也是这两天看代码的总结,如有遗漏,后面再补充!