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

来源:互联网 发布:大疆控制算法笔试题 编辑:程序博客网 时间:2024/05/16 13:48

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

@[Volley, 核心, RequestQueue]

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

  • Volley源码解析四 RequestQueue请求队列
      • RequestQueue结构
      • 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; 网络分发数组

0 0
原创粉丝点击