美文网首页
Volley 解析之 RequestQueue 对象的创建

Volley 解析之 RequestQueue 对象的创建

作者: DJ沸羊羊 | 来源:发表于2019-02-09 14:58 被阅读1次

    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.
         *
         * <ul>
         *     <li>containsKey(cacheKey) indicates that there is a request in flight for the given cache
         *          key.</li>
         *     <li>get(cacheKey) returns waiting requests for the given cache key. The in flight request
         *          is <em>not</em> contained in that list. Is null if no requests are staged.</li>
         * </ul>
         */
        private final Map<String, Queue<Request<?>>> mWaitingRequests =
                new HashMap<String, Queue<Request<?>>>();
    
        /**
         * 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<Request<?>> mCurrentRequests = new HashSet<Request<?>>();
    
        /** The cache triage queue. */
        private final PriorityBlockingQueue<Request<?>> mCacheQueue =
            new PriorityBlockingQueue<Request<?>>();
    
        /** The queue of requests that are actually going out to the network. */
        private final PriorityBlockingQueue<Request<?>> mNetworkQueue =
            new PriorityBlockingQueue<Request<?>>();
    
        private List<RequestFinishedListener> mFinishedListeners =
                new ArrayList<RequestFinishedListener>();
    

    紧接着就是构造函数

        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 对象的创建

          本文链接:https://www.haomeiwen.com/subject/tazasqtx.html