网络通讯框架-Volley源码分析(2)
来源:互联网 发布:mac 怎么设置无线鼠标 编辑:程序博客网 时间:2024/05/01 03:54
HurlStack:SDK>=9被创建
//执行请求 public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { String url = request.getUrl(); HashMap<String, String> map = new HashMap<String, String>(); map.putAll(request.getHeaders()); map.putAll(additionalHeaders); if (mUrlRewriter != null) { String rewritten = mUrlRewriter.rewriteUrl(url); if (rewritten == null) { throw new IOException("URL blocked by rewriter: " + url); } url = rewritten; } URL parsedUrl = new URL(url); HttpURLConnection connection = openConnection(parsedUrl, request);//打开链接 for (String headerName : map.keySet()) { connection.addRequestProperty(headerName, map.get(headerName)); } setConnectionParametersForRequest(connection, request);//设置链接参数 // Initialize HttpResponse with data from the HttpURLConnection. ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);//创建协议版本 int responseCode = connection.getResponseCode(); if (responseCode == -1) { // -1 is returned by getResponseCode() if the response code could not be retrieved. // Signal to the caller that something was wrong with the connection. throw new IOException("Could not retrieve response code from HttpUrlConnection."); } StatusLine responseStatus = new BasicStatusLine(protocolVersion, connection.getResponseCode(), connection.getResponseMessage());//通过给予的版本号、返回状态、和返回信息,创建一个新的状态行 BasicHttpResponse response = new BasicHttpResponse(responseStatus);//通过状态行创建响应 response.setEntity(entityFromConnection(connection)); for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) { if (header.getKey() != null) { Header h = new BasicHeader(header.getKey(), header.getValue().get(0)); response.addHeader(h); } } return response; }
HttpClientStack:SDK<9时被创建
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);//创建请求 addHeaders(httpRequest, additionalHeaders); addHeaders(httpRequest, request.getHeaders()); onPrepareRequest(httpRequest); HttpParams httpParams = httpRequest.getParams(); int timeoutMs = request.getTimeoutMs(); // TODO: Reevaluate this connection timeout based on more wide-scale // data collection and possibly different for wifi vs. 3G. HttpConnectionParams.setConnectionTimeout(httpParams, 5000); HttpConnectionParams.setSoTimeout(httpParams, timeoutMs); return mClient.execute(httpRequest); }
BasicNetwork 执行Volley请求的基础网络
//执行请求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>(); try { // Gather headers. Map<String, String> headers = new HashMap<String, String>(); addCacheHeaders(headers, request.getCacheEntry());//添加缓存头部信息 httpResponse = mHttpStack.performRequest(request, headers);//执行请求,获得响应值 StatusLine statusLine = httpResponse.getStatusLine();//获得状态信息 int statusCode = statusLine.getStatusCode();//获得状态值 responseHeaders = convertHeaders(httpResponse.getAllHeaders());//将Headers[]转换为Map<String, String> // Handle cache validation. if (statusCode == HttpStatus.SC_NOT_MODIFIED) {//如果状态为304,则立即进行返回 return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, request.getCacheEntry().data, responseHeaders, true); } responseContents = entityToBytes(httpResponse.getEntity());//读取响应数据 // 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) {//如果状态不是200或者202,则抛出IO异常 throw new IOException(); } return new NetworkResponse(statusCode, responseContents, responseHeaders, false); } 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); } catch (IOException e) { int statusCode = 0; NetworkResponse networkResponse = null; if (httpResponse != null) {//如果返回不为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); } } } }
CacheDispatcher:缓存执行者线程类
public void run() { if (DEBUG) VolleyLog.v("start new dispatcher"); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); // Make a blocking call to initialize the cache. mCache.initialize(); while (true) { try { // Get a request from the cache triage queue, blocking until // at least one is available. final Request request = mCacheQueue.take();//获得缓存队列里第一个数据 request.addMarker("cache-queue-take");//添加缓存队列标识 // If the request has been canceled, don't bother dispatching it. if (request.isCanceled()) {//如果该请求被取消,则继续执行下一个请求 request.finish("cache-discard-canceled"); continue; } // Attempt to retrieve this item from cache. Cache.Entry entry = mCache.get(request.getCacheKey());//获取缓存对象 if (entry == null) {//如果缓存对象不存在,则标识缓存缺失,并且将该请求放置网络队列,继续执行下一个请求 request.addMarker("cache-miss"); // Cache miss; send off to the network dispatcher. mNetworkQueue.put(request); continue; } // If it is completely expired, just send it to the network. if (entry.isExpired()) {//如果对象过期,则标识缓存过期,则将其发至网络队列,继续执行下一个请求 request.addMarker("cache-hit-expired"); request.setCacheEntry(entry); mNetworkQueue.put(request); continue; } // We have a cache hit; parse its data for delivery back to the request. request.addMarker("cache-hit"); Response<?> response = request.parseNetworkResponse( new NetworkResponse(entry.data, entry.responseHeaders));//解析网络请求数据 request.addMarker("cache-hit-parsed"); if (!entry.refreshNeeded()) {//如果不需要刷新,则通过网络或者缓存直接执行请求 // Completely unexpired cache hit. Just deliver the response. mDelivery.postResponse(request, response); } else {//如果需要刷新,则进行标识,并且将该请求发至网络队列进行刷新 // Soft-expired cache hit. We can deliver the cached response, // but we need to also send the request to the network for // refreshing. request.addMarker("cache-hit-refresh-needed"); request.setCacheEntry(entry); // Mark the response as intermediate. response.intermediate = true; // Post the intermediate response back to the user and have // the delivery then forward the request along to the network. mDelivery.postResponse(request, response, new Runnable() { public void run() { try { mNetworkQueue.put(request); } catch (InterruptedException e) { // Not much we can do about this. } } }); } } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } } }
NetworkDispatcher:网络执行者线程类
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) { 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()) {//如果返回304并且已经返回结果,则不进行第二次的返回 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)); } } }
Response:封转响应对象,用于传递
//使用工厂类设计模式 /** 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); } /** * 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); }
0 0
- 网络通讯框架-Volley源码分析(2)
- 网络通讯框架-Volley源码分析(1)
- 网络通讯框架-Volley源码分析(3)
- 网络通讯框架-Volley源码分析(4)
- Volley框架源码分析
- Android Volley网络通讯框架(Google)
- Volley框架(五):Volley源码分析
- Volley框架核心源码分析
- android-----Volley框架源码分析
- android-----Volley框架源码分析
- 【Android框架】volley源码分析
- 初窥Android网络通讯框架Volley
- Android Volley框架进行网络通讯
- Volley(2)源码分析
- .net网络通讯框架源码
- 开源框架Volley源码分析
- Volley框架中ImageLoader源码分析
- Android之Volley框架源码分析
- MOCK技术,核心代码!
- Android程序对不同手机屏幕分辨率自适应的总结
- C++学习之auto_ptr智能指针
- 物联网时代,智能家居到底离我们有多远
- 手机九宫格加密种数
- 网络通讯框架-Volley源码分析(2)
- 浅谈Lean UX:我们到底该怎么设计?
- 如何美化你的.net 应用程序 (皮肤使用)
- asp.net中把日期(2014/03/25)和时间(14:00)拼接成完整的时间类型
- linux spi驱动
- 一个简单的demo学习Android远程Service(AIDL的使用
- 基于 sql server 数据库,添加字段,删除字段
- ie下console的问题
- Cassandra源代码分析:数据写入流程