Vollery源码阅读(—)

作者: 糖葫芦_倩倩 | 来源:发表于2019-02-22 19:15 被阅读7次

    写在最前面的话:送给还在迷茫看不懂的童鞋,跟着我一步步看,小白也能看懂,从而对整体有一个把握,分析的开始以基本使用为切入点,一步步深入。

    1. 创建获取 RequestQueue 对象

    RequestQueue mQueue = Volley.newRequestQueue(this);
    

    开始进入:::
    Vollery # newRequestQueue()

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
            .....
            if (stack == null) {
                if (VERSION.SDK_INT >= 9) {
                    stack = new HurlStack();
                } else {
                    stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
                }
            }
    
            Network network = new BasicNetwork((HttpStack)stack);
            RequestQueue queue = new RequestQueue(new NoCache(), network);
            queue.start();
            return queue;
        }
    

    看到我开始罗列代码了,不要慌,还好不长,在能力范围内:

    image

    刚开始就根据不同的Android 系统版本,创建不同的对象,我们先可以大概了解一下 HurlStackHttpClientStack 是啥?

    HurlStack.java

    public class HurlStack implements HttpStack {
          ....
        public HttpResponse performRequest(Request<?> request, 
                          Map<String, String>  additionalHeaders) {
                ....
                URL parsedUrl = new URL(url);
                HttpURLConnection connection = this.openConnection(parsedUrl, request); 
               ....
        }
    

    HttpClientStack.java

    public class HttpClientStack implements HttpStack {
        protected final HttpClient mClient;
        ...
        public HttpResponse performRequest(Request<?> request, 
                             Map<String, String> additionalHeaders)  {
              ....
             return this.mClient.execute(httpRequest)
        }
    }
    

    HttpStack.java

    public interface HttpStack {
        HttpResponse performRequest(Request<?> var1, Map<String, String> var2) ;
    }
    

    看到这里我们大概明白了,原来是根据不同的系统版本,确定最终选择进行的网络请求,那为什么大于9 用 HttpUrlConnection 小于9用 HttpClient 呢?在这里不过多介绍了,网上一搜就知道了。

    Ok,那我们继续向下走,回到上面的代码,为了方便查看,我重新粘贴一份代码下来:

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
            .....
            if (stack == null) {
                if (VERSION.SDK_INT >= 9) {
                    stack = new HurlStack();
                } else {
                    stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
                }
            }
            //HttpStack 又一次被封装为Network接口类型
            Network network = new BasicNetwork((HttpStack)stack);
            RequestQueue queue = new RequestQueue(new NoCache(), network);
            queue.start();
            return queue;
        }
    

    Network.java

    public interface Network {
        NetworkResponse performRequest(Request<?> var1) throws VolleyError;
    }
    

    哦 原来是接口,它的实现类 BasicNetwork
    BasicNetwork.java

    public class BasicNetwork implements Network {
        //将网络请求的实例传入,方便后面的调用
      public BasicNetwork(HttpStack httpStack) {
            this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE));
        }
       ....
    }
    

    目前而止,那么它们之间的关系是啥样的呢,我画了一张图:

    image.png
    很清晰吧,目前我们先不考虑这个 BasicNetwork 类中干了什么,我们先根据代码的思路一步步向下走,保证我们整体主干不变,避免陷入只见树木不见森林的局势。

    Ok,我们再次回到原来的代码:

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
            .....
            if (stack == null) {
                if (VERSION.SDK_INT >= 9) {
                    stack = new HurlStack();
                } else {
                    stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
                }
            }
            //HttpStack 又一次被封装为Network接口类型,
           //创建BasicNetwork调用了构造方法是一个参数的
            Network network = new BasicNetwork((HttpStack)stack);
          //到这里了...........
          //创建一个 请求队列 RequestQueue,并且在构造函数中,传入了两个
         //参数,好,我们接下来就要去RequestQueue.java类中看一眼了。
            RequestQueue queue = new RequestQueue(new NoCache(), network);
            queue.start();
            return queue;
        }
    

    RequestQueue.java

    public RequestQueue(Cache cache, Network network) {
            this(cache, network, 2);
        }
    public RequestQueue(Cache cache, Network network, int threadPoolSize) {
            this(cache, network, threadPoolSize, new ExecutorDelivery(new Handler(Looper.getMainLooper())));
        }
    public RequestQueue(Cache cache, Network network, int threadPoolSize, ResponseDelivery delivery) {
            this.mSequenceGenerator = new AtomicInteger();
            this.mWaitingRequests = new HashMap();
            this.mCurrentRequests = new HashSet();
            this.mCacheQueue = new PriorityBlockingQueue();
            this.mNetworkQueue = new PriorityBlockingQueue();
            this.mCache = cache;
            this.mNetwork = network;
            this.mDispatchers = new NetworkDispatcher[threadPoolSize];
            this.mDelivery = delivery;
        }
    

    在构造方法中,传入一个Cache 对象,network 对象,默认初始化一个threadPoolSize = 2,还有一系列初始化操作.

    Ok,再次返回我们之前的代码:

       ....
       RequestQueue queue = new RequestQueue(new NoCache(), network);
      queue.start();
    

    RequestQueue#start() 方法了:

    public void start() {
            this.stop();
            this.mCacheDispatcher = new CacheDispatcher(this.mCacheQueue, this.mNetworkQueue, this.mCache, this.mDelivery);
            this.mCacheDispatcher.start();
    
            for(int i = 0; i < this.mDispatchers.length; ++i) {
                NetworkDispatcher networkDispatcher = new NetworkDispatcher(this.mNetworkQueue, this.mNetwork, this.mCache, this.mDelivery);
                this.mDispatchers[i] = networkDispatcher;
                networkDispatcher.start();
            }
    
        }
    

    这里又创建了一个 CacheDispatcher 类。调用四个参数的构造方法。并调用了 start() 方法。
    接下来,我们就认识下 CacheDispatcher.java 类:

    //原来它是一个线程
    public class CacheDispatcher extends Thread {
    //缓存队列,用BlockingQueue 管理存储
    private final BlockingQueue<Request<?>> mCacheQueue;
    
       public CacheDispatcher(BlockingQueue<Request<?>> cacheQueue, BlockingQueue<Request<?>> networkQueue, Cache cache, ResponseDelivery delivery) {
           //参数赋值
            this.mCacheQueue = cacheQueue;
            this.mNetworkQueue = networkQueue;
            this.mCache = cache;
            this.mDelivery = delivery;
        }
    //调用start 方法必定调用run 方法
     public void run() {
            .....
            Process.setThreadPriority(10);
          //这里初始化缓存,还记得我们之前默认传入了一个 NoCache 吗?
        //这里Cache 是接口,子类有两种NoCache 和 DiskBasedCache两种
            this.mCache.initialize();
          //嵌套了好多循环啊......因为要不断去读取是否有任务嘛,没有的时候就一直等待
            while(true) {
                while(true) {
                    while(true) {
                        while(true) {
                            try {
                              // 表示从缓存队列中取出一个 Request, 那第一次肯定没有啊,就一直等待......
                                final Request<?> request = (Request)this.mCacheQueue.take();
                             .....这里我先省略了,因为还没真正到这一步
    }
    

    OK,返回到我们之前的操作:
    RequestQueue.java

    
    private NetworkDispatcher[] mDispatchers ;
    private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 2;
     public RequestQueue(Cache cache, Network network, int threadPoolSize, ResponseDelivery delivery) {
             ....
            this.mDispatchers = new NetworkDispatcher[threadPoolSize];
            ....
        }
    
    public void start() {
            this.stop();
            this.mCacheDispatcher = new CacheDispatcher(this.mCacheQueue, this.mNetworkQueue, this.mCache, this.mDelivery);
            this.mCacheDispatcher.start();
    
          //到这里啦,
          //从构造方法我们可以得知 mDispatchers.length = 2 ,上
            for(int i = 0; i < this.mDispatchers.length; ++i) {
              
                NetworkDispatcher networkDispatcher = new NetworkDispatcher(this.mNetworkQueue, this.mNetwork, this.mCache, this.mDelivery);
                this.mDispatchers[i] = networkDispatcher;
                networkDispatcher.start();
            }
    
        }
    

    循环遍历生成2 个 NetworkDispatcher 对象,并将 NetworkDispatcher 对象存储在一个 mDispatchers 的数组中去了,最后调用了 start 方法。
    Ok,那接下来我们就看下这个 NetworkDispatcher.java 类了。

    NetworkDispatcher.java

    public class NetworkDispatcher extends Thread {
          // 网络请求队列
           private final BlockingQueue<Request<?>> mQueue;
    
            //对象初始化
            public NetworkDispatcher(BlockingQueue<Request<?>> queue, Network network, Cache cache, ResponseDelivery delivery) {
            this.mQueue = queue;
            this.mNetwork = network;
            this.mCache = cache;
            this.mDelivery = delivery;
        }   
    //既然是线程,调用 start 方法,必定调用 run 方法
    public void run() {
            Process.setThreadPriority(10);
    
          //线程也是,既然要做网络请求,就要一直等待获取
            while(true) {
                Request request;
                while(true) {
                    try {
                      // 从网络请求队列中获取任务,那一开始我们初始化肯定没东西,队列里没请求任务
                        request = (Request)this.mQueue.take();
                        break;
                    } catch (InterruptedException var4) {
                        if (this.mQuit) {
                            return;
                        }
                    }
                }
          .....底部代码我也省略了,因为都是获取到请求之后所做的处理      
    

    至此,对于RequestQueue 的初始化第一步我们完成了对它的了解,你明白了吗? 下一篇我们针对 mQueue.add(request) 真正需要进行网络请求进行继续分析。如果这篇文章有帮助到你,给个赞就是我最大的鼓励了,比心💗。

    相关文章

      网友评论

        本文标题:Vollery源码阅读(—)

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