Android网络框架volley学习(五)请求队列RequestQueue简析

RequestQueue:表示请求队列,查看源码得知,里面包含一个CacheDispatcher(用于处理走缓存请求的调度线程)、NetworkDispatcher数组(用于处理走网络请求的调度线程),一个ResponseDelivery(返回结果分发接口),通过 start() 函数启动时会启动CacheDispatcher和NetworkDispatchers。

本篇内容我们来详细的了解一下RequestQueue相关内容。

源码路径com.android.volley.RequestQueue

在使用Request时,首先需要创建一个请求队列RequestQueue,

RequestQueue queue = Volley.newRequestQueue(this);

//创建出请求队列后调用start开始启动队列
private static RequestQueue newRequestQueue(Context context, Network network) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();
        return queue;
}

这个请求队列的构造比较简单,内部通过判断SDK的版本来进行判断来使用哪个网络请求方式,相关文章请查看《Android网络框架volley学习(三)底层网络请求分析》。我们进入到RequestQueue的内部详细看下源码。

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

以上是它的构造函数,里面有四个参数,分别是:

  1. 缓存方式,默认是硬盘缓存
  2. 网络对象,即网络底层实现方式
  3. 线程池大小,默认有4个网络请求线程
  4. 结果返回对象

另外还存在其他两个构造函数,不过最终都是调用的最基本的构造方法。



 public RequestQueue(Cache cache, Network network, int threadPoolSize) {
        this(cache, network, threadPoolSize,
                new ExecutorDelivery(new Handler(Looper.getMainLooper())));
    }


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

默认情况下,请求队列RequestQueue是通过Volley工具类产生的即:

RequestQueue queue = Volley.newRequestQueue(this);

不过通过它的共有构造方法,我们可以生成自己的请求队列,即采用自定义的HttpStatck,采用自定义的Network实现,采用自定义的 Cache 实现等来构建RequestQueue

请求队列RequestQueue构造后,我们会产生一个基本的请求,如 StringRequest、JsonObjectRequest、 JsonArrayRequest等或者自己实现的请求方式,最后将生成的网络请求添加到请求队列中,即

StringRequest mStringRequest=new StringRequest("url", new Response.Listener() {
            @Override
            public void onResponse(String response) {

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        //将请求添加到请求队列中
        queue.add(mStringRequest);

开始的时候我们构造出请求队列后,将会调用start方法,开启请求队列。

    public void start() {
        stop();   
        mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
        mCacheDispatcher.start();

        for (int i = 0; i < mDispatchers.length; i++) {
            NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
                    mCache, mDelivery);
            mDispatchers[i] = networkDispatcher;
            networkDispatcher.start();
        }
    }

开启请求队列比较简单,主要就是缓存调度开启工作和网络调度开启工作。接着我们接着进入到add中去分析一下源码。


    public  Request add(Request request) {

        request.setRequestQueue(this);
        synchronized (mCurrentRequests) {
            mCurrentRequests.add(request);
        }

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

        if (!request.shouldCache()) {
            mNetworkQueue.add(request);
            return request;
        }
        mCacheQueue.add(request);
        return request;
     }

对于add方法,将当前的请求添加到请求队列中,参数是Request,它是一个抽象类,需要我们自己实现,可以是StringRequest或者我们自己实现的请求。

在这里面维护了一个当前请求集合,当前请求队列处理的所有请求都将放入到该集合中去,后续的请求也将会放入到该集合中来。

/**
     * The set of all requests currently being processed by this RequestQueue. A Request
     * will be in this set if it is waiting in any queue or currently being processed by
     * any dispatcher.
     */
    private final Set> mCurrentRequests = new HashSet>();

放入到请求集合中后进行处理,首先判断是否需要放入到缓存队列中去,如果不需要的话则直接放到网络请求队列中去。

关于缓存队列和网络请求队列,我们下篇再进行详细分析。进过一系列的操作,一条请求就完成了。我们继续看RequestQueue中其他的方法。既然可以发起请求,当然也可以取消请求,取消当前的请求通过cancelAll(final Object tag) 方法来操作。

/**
     * Cancels all requests in this queue with the given tag. Tag must be non-null
     * and equality is by identity.
     */
    public void cancelAll(final Object tag) {
        if (tag == null) {
            throw new IllegalArgumentException("Cannot cancelAll with a null tag");
        }
        cancelAll(new RequestFilter() {
            @Override
            public boolean apply(Request request) {
                return request.getTag() == tag;
            }
        });
    }

对于请求的取消,主要是通过发起请求时设置的tag来判别是哪个请求需要取消。当一条请求完成后,我们需要将它从请求队列中移除掉。即在当前的集合中去掉该请求。

/**
     * Called from {@link Request#finish(String)}, indicating that processing of the given request
     * has finished.
     */
     void finish(Request request) {
        // Remove from the set of requests currently being processed.
        synchronized (mCurrentRequests) {
            mCurrentRequests.remove(request);
        }
        synchronized (mFinishedListeners) {
          for (RequestFinishedListener listener : mFinishedListeners) {
            listener.onRequestFinished(request);
          }
        }

    }

以上便是volley里面关于请求队列的一些信息。

你可能感兴趣的:(Android网络框架volley学习(五)请求队列RequestQueue简析)