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