[Android]Volley源碼分析(五)

來源:互聯網
上載者:User

請求結果的交付是通過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 the21                 // 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 the15      * 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         @Override31         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 done46             // 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 @Override2     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             @Override5             public void execute(Runnable command) {6                 handler.post(command);7             }8         };9     }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.