Volley 解析之 RequestQueue 对象的创建

RequestQueue:

RequestQueue的创建:

Volley.newRequestQueue

RequestQueue 初始化之前会初始化下面几个容器

/** Used for generating monotonically-increasing sequence numbers for requests. */
    private AtomicInteger mSequenceGenerator = new AtomicInteger();

    /**
     * Staging area for requests that already have a duplicate request in flight.
     *
     * 
    *
  • containsKey(cacheKey) indicates that there is a request in flight for the given cache * key.
  • *
  • get(cacheKey) returns waiting requests for the given cache key. The in flight request * is not contained in that list. Is null if no requests are staged.
  • *
*/ private final Map>> mWaitingRequests = new HashMap>>(); /** * 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>(); /** The cache triage queue. */ private final PriorityBlockingQueue> mCacheQueue = new PriorityBlockingQueue>(); /** The queue of requests that are actually going out to the network. */ private final PriorityBlockingQueue> mNetworkQueue = new PriorityBlockingQueue>(); private List mFinishedListeners = new ArrayList();

紧接着就是构造函数

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }
        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                /** Prior to Gingerbread, HttpUrlConnection was unreliable. */
                /** See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html */
              stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();

        return queue;
    }

这里我们只讨论Android sdk 9(Android 2.3) 以上的版本,并且用户没有自定 HttpStack 的情况.
在这里我们看到 newRequestQueue里创建了 4个对象,分别是:

  1. File cacheDir.
  2. HurlStack stack:
public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) {
        mUrlRewriter = urlRewriter;// urlRewriter ==null
        mSslSocketFactory = sslSocketFactory; // sslSocketFactory ==null
}

通过源码得知,创建 HurlStack 并未做任何其他操作,只是创建了一个对象而已

  1. BasicNetwork network.
public BasicNetwork(HttpStack httpStack) {
        /** If a pool isn't passed in, then build a small default pool that will give us a lot of */
        /** 翻译:如果没有传入池,那么构建一个小的默认池,它将为我们提供很多 */
        /** benefit and not use too much memory */
        /** 翻译:受益,而不是使用太多的记忆 */
        this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE));
        /** DEFAULT_POOL_SIZE == 4096 */
    }

这里创建 BasicNetwork 时,创建了一个 ByteArrayPool 对象, ByteArrayPool 创建时,创建了一个 LinkedList,以及 一个 ArrayList 用于实现缓存,这里创建的 ArrayList 预初始化长度 为 64,也就是说这里有了一点内存开销.

  1. RequestQueue queue.
 public RequestQueue(Cache cache, Network network, int threadPoolSize,
            ResponseDelivery delivery) {
        
        /** DiskBasedCache */
        mCache = cache; 
        
        /** BasicNetwork */
        mNetwork = network;
        
        /** threadPoolSize = 4*/
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        
         /** new ExecutorDelivery(new Handler(Looper.getMainLooper()) */
        mDelivery = delivery;
    }
这里新建了一些对象:

DiskBasedCache:
产生了一些实现缓存的内存开销.

ResponseDelivery:
    1. Handler 
    1. Executor 这里的Executor 用于执行线程转换,将其他工作线程的执行结果 发送到主线程执行,没什么特殊处理或操作,它的主要代码执行片段如下:
 private class ResponseDeliveryRunnable implements Runnable {
        private final Request mRequest;
        private final Response mResponse;
        private final Runnable mRunnable;

        public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
            mRequest = request;
            mResponse = response;
            mRunnable = runnable;
        }

        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            // If this request has canceled, finish it and don't deliver.
            if (mRequest.isCanceled()) {
                mRequest.finish("canceled-at-delivery");
                return;
            }

            // Deliver a normal response or error, depending.
            if (mResponse.isSuccess()) {
                mRequest.deliverResponse(mResponse.result);
            } else {
                mRequest.deliverError(mResponse.error);
            }

            // If this is an intermediate response, add a marker, otherwise we're done
            // and the request can be finished.
            if (mResponse.intermediate) {
                mRequest.addMarker("intermediate-response");
            } else {
                mRequest.finish("done");
            }

            // If we have been provided a post-delivery runnable, run it.
            if (mRunnable != null) {
                mRunnable.run();
            }
       }
    }

NetworkDispatcher:
1.创建了4个 Thread 对象(仅仅是创建对象,目前尚未产生线程开销),产生线程开销的时机可能在后面的业务执行时.

RequestQueue 对象创建好了之后,会立即执行 start函数,每次调用 start函数都会重新创建 一个CacheDispatcher,该对象是一个Volley自定义的线程对象,并且会马上调用该线程start函数,产生了一次线程创建开销(个人对线程开销的理解是,如果仅仅是new Thread 而不调用start 函数,那么他只是一个普通的对象,一旦调用了 start 函数,那么就产生了一些列的线程开销,就java而言,新建一个线程的开销的是很大的,当然我的观点是就线程开销而言,并没有说是Volley的作者这么写有问题,Volley的这种实现方式是基于它的需求驱动的结果,如果我们可以使用线程池完成业务实现,还是使用线程池实现比较好.).
RequestQueue 对象的创建部分就告一段落了,接下来就是 RequestQueue的各个函数实现

你可能感兴趣的:(Volley 解析之 RequestQueue 对象的创建)