volley框架-请求流程篇

虽说volley已经好多年了,最近打算开始写一些博客,就从最开始用过的框架开始些吧。

这一篇只是简单写一下volley网络请求的过程,下一篇打算写写volley 的cache机制

先放一张volley的官方运行流程图,讲述了volley中一个request的执行过程,可以看到,volley主要分成了三种线程,分别是

  1. 主线程

  2. cache线程

  3. 网络线程(包含多个线程)

 

下面看一次网络请求流程

1 构建一个RequestQueue

2 构造一个Request

3 RequestQueue.add(Request)

4 RequestQueue.start() //该方法不一定非要添加request后再执行

 

这样就很清晰了,先看一下RequestQueue的add方法

/**

* Adds a Request to the dispatch queue.

*

* @param request The request to service

* @return The passed-in request

*/

public <T> Request<T> add(Request<T> request) {

    // Tag the request as belonging to this queue and add it to the set of current requests.

    request.T(this);

    synchronized (mCurrentRequests) {

        mCurrentRequests.add(request);

    }



    // Process requests in the order they are added.

    request.setSequence(getSequenceNumber());

    request.addMarker("add-to-queue");



    // If the request is uncacheable, skip the cache queue and go straight to the network.

    if (!request.shouldCache()) {

        mNetworkQueue.add(request);

        return request;

    }

    mCacheQueue.add(request);

    return request;

}


把 Request 添加到当前的请求集合中

给这个请求设置序列号

判断是否需要cache,

不需要直接加入网络请求队列,返回

需要cache将请求添加到cache队列中

 

继续看start方法

/** Starts the dispatchers in this queue. */

public void start() {

    stop(); // Make sure any currently running dispatchers are stopped.

    // Create the cache dispatcher and start it.

    mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);

    mCacheDispatcher.start();



    // Create network dispatchers (and corresponding threads) up to the pool size.

    for (int i = 0; i < mDispatchers.length; i++) {

        NetworkDispatcher networkDispatcher =

                new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery);

        mDispatchers[i] = networkDispatcher;

        networkDispatcher.start();

    }

}

 

可以看出这里新创建了一个CacheDispatcher,和若干个NetworkDispatcher,然后调用start方法。

实际上,他们就是新创建的几个线程,这样一来就能跟最上面的整体架构图对上了,一个cache线程,多个网络请求线程(默认4个)

NetworkDispatcher 与 CacheDispatcher 继承自Thread

 

下面看一下CacheDispatcher的主要方法

@Override

public void run() {

    if (DEBUG) VolleyLog.v("start new dispatcher");

    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);



    // Make a blocking call to initialize the cache.

    mCache.initialize();



    while (true) {

        try {

            // Process request if cache not hit, add it to mNetworkQueue

            processRequest(); 

        } catch (InterruptedException e) {

            // We may have been interrupted because it was time to quit.

            if (mQuit) {

                Thread.currentThread().interrupt();

                return;

            }

            VolleyLog.e(

                    "Ignoring spurious interrupt of CacheDispatcher thread; "

                            + "use quit() to terminate it");

        }

    }

}



private void processRequest() throws InterruptedException {

    // Get a request from the cache triage queue, blocking until

    // at least one is available.

    final Request<?> request = mCacheQueue.take();

    processRequest(request);

}

总结一下就是CacheDispatcher这个线程不断轮询,取出当前需要处理的请求进行处理,如果cache不能够命中或者已经过期需要刷新就将这个request添加到NetworkDispatcher中进行处理

NetworkDispatcher默认是4个

CacheDispatcher的run方法一样NetworkDispatcher也是不断循环,取出当前队列中的request进行处理,这里主要看一下如何返回请求的

void processRequest(Request<?> request) {

    long startTimeMs = SystemClock.elapsedRealtime();

    try {

        request.addMarker("network-queue-take");



        // If the request was cancelled already, do not perform the

        // network request.

        if (request.isCanceled()) {

            request.finish("network-discard-cancelled");

            request.notifyListenerResponseNotUsable();

            return;

        }



        addTrafficStatsTag(request);



        // Perform the network request.

        NetworkResponse networkResponse = mNetwork.performRequest(request);

        request.addMarker("network-http-complete");



        // If the server returned 304 AND we delivered a response already,

        // we're done -- don't deliver a second identical response.

        if (networkResponse.notModified && request.hasHadResponseDelivered()) {

            request.finish("not-modified");

            request.notifyListenerResponseNotUsable();

            return;

        }



        // Parse the response here on the worker thread.

        Response<?> response = request.parseNetworkResponse(networkResponse);

        request.addMarker("network-parse-complete");



        // Write to cache if applicable.

        // TODO: Only update cache metadata instead of entire record for 304s.

        if (request.shouldCache() && response.cacheEntry != null) {

            mCache.put(request.getCacheKey(), response.cacheEntry);

            request.addMarker("network-cache-written");

        }



        // Post the response back.

        request.markDelivered();

        mDelivery.postResponse(request, response);

        request.notifyListenerResponseReceived(response);

    } catch (VolleyError volleyError) {

        volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);

        parseAndDeliverNetworkError(request, volleyError);

        request.notifyListenerResponseNotUsable();

    } catch (Exception e) {

        VolleyLog.e(e, "Unhandled exception %s", e.toString());

        VolleyError volleyError = new VolleyError(e);

        volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);

        mDelivery.postError(request, volleyError);

        request.notifyListenerResponseNotUsable();

    }

}

可以看出这段代码关键的地方有两处,一处是发送网络请求返回结果,一处mDelivery.postResponse将结果返回

在主线程执行

总体结构

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值