fenggit

学无止境,永不止步

Volley源码解析<四> RequestQueue请求队列

Volley源码解析<四> RequestQueue请求队列

@[Volley, 核心, RequestQueue]

声明:转载请注明出处,知识有限,如有错误,请多多交流指正!

RequestQueue结构

RequestQueue类

1. 构造方法

RequestQueue是请求队列,负责分发请求,取缓存或读网络,所以其构造函数中需要一个Cache对象和一个Network对象,还有一个ResponseDelivery对象用于派发结果


 public RequestQueue(Cache cache, Network network) {
        this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
 }

public RequestQueue(Cache cache, Network network, int threadPoolSize) {
        //传递一个与主线程的Looper关联的一个Handler
        this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper())));
}

public RequestQueue(Cache cache, Network network, int threadPoolSize, ResponseDelivery delivery) {
        mCache = cache;
        mNetwork = network;
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        mDelivery = delivery;
    }

其中

mCache : 缓存数据
mNetwork :网络请求
mDispatchers :网络请求调度线程(默认开启4个)
mDelivery :分发响应解析后的数据对象
ExecutorDelivery:结果回调监听分发,请求数据解析后,通过此类回调给调用者,传递一个与主线程的Looper关联的一个Handler,这样做的好处就是调用者可以在回调中更新UI

2. 存储数据集合
存储数据
PriorityBlockingQueue:是优先级阻塞队列,在这个数据结构,元素是按照顺序储存的。元素们必须实现 带有compareTo()方法的 Comparable 接口。当你在结构中插入数据时,它会与数据元素对比直到找到它的位置;当从队列中获取数据的时候,如果没有数据的时候,会阻塞在take()方法

队列之间的关系:每当一个请求到来时,先加入到mCurrentRequests,然后判断当前Request是否需要缓存,如果不用缓存的Request,则直接加入到mNetworkQueue队列中等待网络处理器(NetWorkDispatcher)去处理。如果需要缓存的话,根据Request获取相应的cacheKey,如果cacheKey不存在的话,说明这个需要缓存的Request是第一次请求。那么将cacheKey放入到mWaitingRequests队列里。mWaitingRequests里存放的是mCacheQueue里已经有相同url的Request,并将Request放入到mCacheQueue中以做处理

mCurrentRequests:存储当前请求,主要用于取消请求
mWaitingRequests:主要是为了避免不必要的网络数据获取

3. 启动所有调度器线程

    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.
        // 网络请求调度器,默认开启DEFAULT_NETWORK_THREAD_POOL_SIZE(4)个线程,相当于线程池
        for (int i = 0; i < mDispatchers.length; i++) {
            NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery);
            mDispatchers[i] = networkDispatcher;
            networkDispatcher.start();
        }
    }

开启1个缓存线程,4个网络请求线程(相当于线程池),当将请求add到PriorityBlockingQueue的时候,在运行缓存和网络线程就会接收到请求,从而去处理相对应的请求会阻塞

CacheDispatcher:缓存请求线程
NetworkDispatcher:网络请求调度器

4. 将一个请求加入请求队列中

    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.setRequestQueue(this); //为Request设置请求队列

        //将请求add到当前请求队列中
        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;
        }

        // Insert request into stage if there's already a request with the same cache key in flight.
        //缓存,首先判断是否有相同请求正在处理
        synchronized (mWaitingRequests) {
            String cacheKey = request.getCacheKey();

            //有相同请求正在处理
            if (mWaitingRequests.containsKey(cacheKey)) {
                // There is already a request in flight. Queue up.
                Queue<Request<?>> stagedRequests = mWaitingRequests.get(cacheKey);
                if (stagedRequests == null) {
                    stagedRequests = new LinkedList<Request<?>>();
                }
                stagedRequests.add(request);
                //处理等待队列空数据,加入到等待队列
                mWaitingRequests.put(cacheKey, stagedRequests);

                if (VolleyLog.DEBUG) {
                    VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);
                }
            } else {
                // Insert 'null' queue for this cacheKey, indicating there is now a request in
                // flight.
                // 创建新的等待当前请求的空队列添加到当前请求缓存队列中
                mWaitingRequests.put(cacheKey, null);
                mCacheQueue.add(request);
            }
            return request;
        }
    }

5. 其他方法

 > public void stop() 停止所有调度器线程
 > <T> void finish(Request<T> request) 请求结束调用
 > public void cancelAll(final Object tag) 通过Tag取消请求

6. 其他涉及到的类(后续解析)

private final ResponseDelivery mDelivery; 通过子类ExecutorDelivery响应结果分发
private final Network mNetwork; 通过子类BasicNetwork封装网络请求HttpStack,用于执行网络请求
private AtomicInteger mSequenceGenerator = new AtomicInteger(); 生成唯一标识符
private NetworkDispatcher[] mDispatchers; 网络分发数组

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fenggit/article/details/50727768
个人分类: Volley框架解析
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭