1.爲何咱們在發起請求的時候,只須要往隊列中插入一個request就能夠了?
答:由於咱們在建立requestQueue的時候,會調用Volley.newRequestQueue(Context context, HttpStack stack)方法:segmentfault
public static RequestQueue newRequestQueue(Context context, HttpStack stack) { ... Network network = new BasicNetwork(stack); RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network); queue.start(); return queue; }
其中會調用RequestQueue的start方法,如今咱們來看看RequestQueue的start方法:網絡
public void start() { ... for (int i = 0; i < mDispatchers.length; i++) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,mCache, mDelivery); mDispatchers[i] = networkDispatcher; networkDispatcher.start(); } }
NetworkDispatcher是一個線程,裏面在run方法,會有一個循環,一直取mNetworkQueue,mNetworkQueue是一個BlockQueue,經過take進行取值,取到了,而後執行mNetwork.performRequest(request):
2.parseNetWorkResponse在何時調用的?
答:ide
@Override public void run() { ... // Perform the network request. NetworkResponse networkResponse = mNetwork.performRequest(request); ... Response<?> response = request.parseNetworkResponse(networkResponse); request.addMarker("network-parse-complete"); ... request.markDelivered(); mDelivery.postResponse(request, response); ... }
NetWorkDispatcher的run方法,在執行完mNetwork.performRequest方法,即BasicNetWork的performRequest方法,拿到netWorkResponse,會調用request.parseNetworkResponse(networkResponse);因此咱們在繼承request的時候,重寫parseNetworkResponse(networkResponse)方法,就能對網絡請求的數據進行自定義的解析轉換。oop
3.在工做線程執行完網絡請求,怎麼對回調在主線程,讓主線程對解析後的數據進行業務處理?
從上面的代碼咱們能夠看到,在解析完數據以後,咱們會執行postResponse,這裏的mDelivery對應的是ExecutorDelivery類的實例,咱們能夠看ExecutorDelivery的postResponse(request, response)方法:post
@Override public void postResponse(Request<?> request, Response<?> response, Runnable runnable) { request.markDelivered(); request.addMarker("post-response"); mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable)); }
在postResponse(request, response)方法中會調用mResponsePoster的execute方法,咱們如今來看下它的方法的實現:spa
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); } }; }
的execute方法,本質上是執行了Handler的post(Runnable)方法,然而咱們在建立requestQueue的時候,咱們實例ExecutorDelivery對象的時候,傳的handler對應的looper是主線程的sMainLooper,那經過post的執行的任務咱們是會執行將runnable封裝成message發到主線程的messageQueue當中,而後主線程的Looper去取message來執行。(若是對handler中傳遞sMainLooper,而後執行就在主線程的緣由,能夠看下https://segmentfault.com/a/11...)
4.在主線程中執行message,怎麼經過接口的形式將數據response中的泛型對象,傳遞給業務層?
答:咱們能夠看到上面發送請求的時候,咱們會封裝一個ResponseDeliveryRunnable,經過handle.post(runnable),咱們會執行ResponseDeliveryRunnable的run方法:線程
public void run() { ... if (mResponse.isSuccess()) { mRequest.deliverResponse(mResponse.result); } else { mRequest.deliverError(mResponse.error); } ... }
因此,咱們在集成Request的時候,須要重寫deliverResponse(T response),這裏就是底層訪問完數據,將數據傳給業務方,這個方法是主線程執行的。
總結:通過上面的分析,我相信你們應該在用volley的時候,爲何須要實現deliverResponse和parseNetworkResponse方法應該明白了吧,deliverResponse就是用來將網絡獲取的數據傳遞給業務方,parseNetworkResponse是你對網絡拿到的數據,怎麼解析成本身想要的數據形式。code