由Volley的GsonRequest引起的思考

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

相關文章
相關標籤/搜索