1.NetWorkDispatcher.java
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; // 用于关闭线程...
public NetworkDispatcher(BlockingQueue<Request> queue, Network network, Cache cache, ResponseDelivery delivery) { mQueue = queue; mNetwork = network; mCache = cache; mDelivery = delivery; }
@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
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; }
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对象...
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; }
@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); } } } }
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()); }
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)); } }
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)); }
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; }
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(); } }
4.NetWorkResponse.java
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响应的判断... }
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; } }
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); //发送错误信息... }
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(); } } } }
abstract protected void deliverResponse(T response);
public interface Listener<T> { /** Called when a response is received. */ public void onResponse(T response); }