AG环亚娱乐_AG直营网_环亚娱乐AG最佳线路_搜狐新闻
web技术

热门文章

当前位置:主页 > 热门文章 >

联系我们

CONTACT

地址:
电话:
传真:
邮箱:

[Android]Volley源码分析(五)

2019-01-28

请求结果的交付是通过ResponseDelivery接口完成的,它有一个实现类ExecutorDelivery, 主要有postResponse()与postError()两个方法,分别在请求成功或失败时将结果提交给请求发起者。   1. 首先,在NetworkDispatcher的run()方法中,当服务器返回响应并解析完后,会调用mDelivery.postResponse(网易新闻request, response);来提交请求响应。   复制代码  1  @Override  2     public void run() {  3         Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  4         Request<?> request;  5         while (true) {  6             try {  7                 // Take a request from the queue.  8                 request = mQueue.take();  9             } catch (InterruptedException e) { 10                 // We may have been interrupted because it was time to quit. 11                 if (mQuit) { 12                     return; 13                 } 14                 continue; 15             } 16  17             try { 18                 request.addMarker("network-queue-take"); 19  20                 // If the request was cancelled already, do not perform the 21                 // network request. 22                 if (request.isCanceled()) { 23                     request.finish("network-discard-cancelled"); 24                     continue; 25                 } 26  27                 addTrafficStatsTag(request); 28  29                 // Perform the network request. 30                 NetworkResponse networkResponse = mNetwork.performRequest(request); 31                 request.addMarker("network-http-complete"); 32  33                 // If the server returned 304 AND we delivered a response already, 34                 // we're done -- don't deliver a second identical response. 35                 if (networkResponse.notModified && request.hasHadResponseDelivered()) { 36                     request.finish("not-modified"); 37                     continue; 38                 } 39  40                 // Parse the response here on the worker thread. 41                 Response<?> response = request.parseNetworkResponse(networkResponse); 42                 request.addMarker("network-parse-complete"); 43  44                 // Write to cache if applicable. 45                 // TODO: Only update cache metadata instead of entire record for 304s. 46                 if (request.shouldCache() && response.cacheEntry != null) { 47                     mCache.put(request.getCacheKey(), response.cacheEntry); 48                     request.addMarker("network-cache-written"); 49                 } 50  51                 // Post the response back. 52                 request.markDelivered(); 53                 mDelivery.postResponse(request, response); 54             } catch (VolleyError volleyError) { 55                 parseAndDeliverNetworkError(request, volleyError); 56             } catch (Exception e) { 57                 VolleyLog.e(e, "Unhandled exception %s", e.toString()); 58                 mDelivery.postError(request, new VolleyError(e)); 59             } 60         } 61     } 复制代码 2. 看ExecutorDelivery中postResponse()方法的具体实现。其中mResponsePoster是一个Executor。每post一个response,都会调用ResponseDeliveryRunnable的run()方法。在这个run()方法中,会通过mRequest.deliverResponse(mResponse.result)来传递response的result,这个result其实就是已经解析好的响应结果,比如一个表示处理结果的字符串或一个User对象。   复制代码  1 @Override  2     public void postResponse(Request<?> request, Response<?> response) {  3         postResponse(request, response, null);  4     }  5   6     @Override  7     public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {  8         request.markDelivered();  9         request.addMarker("post-response"); 10         mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable)); 11     } 12  13 /** 14      * A Runnable used for delivering network responses to a listener on the 15      * main thread. 16      */ 17     @SuppressWarnings("rawtypes") 18     private class ResponseDeliveryRunnable implements Runnable { 19         private final Request mRequest; 20         private final Response mResponse; 21         private final Runnable mRunnable; 22  23         public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) { 24             mRequest = request; 25             mResponse = response; 26             mRunnable = runnable; 27         } 28  29         @SuppressWarnings("unchecked") 30         @Override 31         public void run() { 32             // If this request has canceled, finish it and don't deliver. 33             if (mRequest.isCanceled()) { 34                 mRequest.finish("canceled-at-delivery"); 35                 return; 36             } 37  38             // Deliver a normal response or error, depending. 39             if (mResponse.isSuccess()) { 40                 mRequest.deliverResponse(mResponse.result); 41             } else { 42                 mRequest.deliverError(mResponse.error); 43             } 44  45             // If this is an intermediate response, add a marker, otherwise we're done 46             // and the request can be finished. 47             if (mResponse.intermediate) { 48                 mRequest.addMarker("intermediate-response"); 49             } else { 50                 mRequest.finish("done"); 51             } 52  53             // If we have been provided a post-delivery runnable, run it. 54             if (mRunnable != null) { 55                 mRunnable.run(); 56             } 57        } 58     } 复制代码 3. 既然是通过Request的deliverResponse()来传递响应结果,就来看下这个方法, 第二篇中已经知道这个方法是个抽象函数,由它子类来实现。以第一篇中的MyGsonRequest为例,其实现很简单,就是调用了mListener的onResponse方法。   1 @Override 2     protected void deliverResponse(T response) { 3         mListener.onResponse(response); 4     } 这个mListener就是在主线程实例化MyGsonRequest的时候,传过来的一个Response.Listener<T>实例,这是MyGsonRequest的构造函数:   复制代码  1 public MyGsonRequest(int method  2                         , String url                          3                         , Object requestBody  4                         , Class<T> responseClass  5                         , Listener<T> listener  6                         , ErrorListener errorListener) {  7           8         super(method, url, errorListener);  9         this.mRequestBody = requestBody; 10         this.mResponseClass = responseClass; 11         this.mListener = listener; 12         mGson = new Gson(); 13          14     } 复制代码 这里mListener也就是第一篇中在主线程中通过createRegisterSuccessListener函数返回的监听器实例,如下代码所示。  所以最终会调到这里的onResponse()方法,来做一些更新UI或提示用户请求成功之类的操作。请求失败时,响应错误结果的提交与之类似。这样,Volley就完成了响应结果的交付。   复制代码  1 private Listener<String> createRegisterSuccessListener() {  2         return new Listener<String>() {  3             @Override  4             public void onResponse(String response) {  5                 if (mProgressDialog != null) {  6                     mProgressDialog.dismiss();  7                 }  8                 Toast.makeText(  9                         RegisterActivity.this, 10                         getString(R.string.msg_register_success), 11                         Toast.LENGTH_SHORT).show(); 12  13             } 14         }; 15     } 复制代码 这里还有一个问题, 因为更新UI的操作只能在主线程中进行,那么ResponseDeliveryRunnable的run()方法不能再新起一个线程来执行,而应该在主线程中执行,这个是如何做到的?   其实还是用的Handler,Looper,MessageQueue的那套机制。 在Volley初始化一个RequestQueue的时候,会调用RequestQueue的如下构造函数,它构建了一个ExecutorDelivery对象,并把一个与主线程的Looper关联的一个Handler,   1 public RequestQueue(Cache cache, Network network, int threadPoolSize) { 2         this(cache, network, threadPoolSize, 3                 new ExecutorDelivery(new Handler(Looper.getMainLooper()))); 4     } 然后再看下ExecutorDelivery的构造方法, 通过handler的post方法,把ResponseDeliveryRunnable 这个runnable加到了主线程的消息队列中,所以它的run()方法是在主线程中执行的。   复制代码 1     public ExecutorDelivery(final Handler handler) { 2         // Make an Executor that just wraps the handler. 3         mResponsePoster = new Executor() { 4             @Override 5             public void execute(Runnable command) { 6                 handler.post(command); 7             } 8         }; 9     }

http://www.bkjia.com/Androidjc/822477.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/822477.htmlTechArticle请求结果的交付是通过ResponseDelivery接口完成的,它有一个实现类ExecutorDelivery, 主要有postResponse()与postError()两个方法,分别在请求成功或失败...

本文源自: AG环亚娱乐

上一篇:Android程序崩溃异常收集框架

下一篇:没有了

【返回列表】

Copyright © 2005-2017 http://www.turingvr.com AG环亚娱乐_AG直营网_环亚娱乐AG最佳线路_搜狐新闻版权所有

友情链接: