zoukankan      html  css  js  c++  java
  • Android.Volley的解读:初始接触volley

    public RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());

    一切都从这句代码开始。。。

    跟着newRequestQueue(Context)到Volley类中

    public class Volley {
         ...
         public static RequestQueue newRequestQueue(Context context) {
            return newRequestQueue(context, null);
        }  
    }
     1 public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
     2         File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
     3 
     4         String userAgent = "volley/0";
     5         try {
     6             String packageName = context.getPackageName();
     7             PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
     8             userAgent = packageName + "/" + info.versionCode;
     9         } catch (NameNotFoundException e) {
    10         }
    11 
    12         if (stack == null) {//你开始传null,所以走这里
    13             if (Build.VERSION.SDK_INT >= 9) {
    14                 stack = new HurlStack();//SDK如果大于等于9,也就是Android 2.3以后,因为引进了HttpUrlConnection 
    15             } else {//如果小于9,则是用HttpClient来实现
    16                 // Prior to Gingerbread, HttpUrlConnection was unreliable.
    17                 // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
    18                 stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
    19             }
    20         }
    21 
    22         Network network = new BasicNetwork(stack);
    23       //创建一个Network,参数stack是用来网络通信
    24         RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
    25         queue.start();
    26 
    27         return queue;
    28     }

    接下来就是RequestQueue了,F2跟进去

    public RequestQueue(Cache cache, Network network) {
            this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
        }
    
     ...
    
    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) {
            mCache = cache;  //private final Cache mCache用于缓存
            mNetwork = network;  //private final Network mNetwork用于连接网络
            mDispatchers = new NetworkDispatcher[threadPoolSize];  /NetworkDispatcher继承thread,网络派发线程池
            mDelivery = delivery;  // 传递Response的实现
        }

    以上四个参数中,前两个是传入参数,后两个参数,threadPoolSize线程池数,默认为4,剩下最后一个,进入ExecutorDelivery(new Handler(Looper.getMainLooper()))

    public ExecutorDelivery(final Handler handler) {
            // Make an Executor that just wraps the handler.
            mResponsePoster = new Executor() {
                @Override
                public void execute(Runnable command) {
                    handler.post(command);
                }
            };
        }

    可以看到Handler将Response传回主线程,进行更新。

    自此,代码RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network),已经执行完,下一句就是queue.start()了

    看看start的代码,如下

    /**
         * Starts the dispatchers in this queue.
         */
        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.
            for (int i = 0; i < mDispatchers.length; i++) {
                NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
                        mCache, mDelivery);
                mDispatchers[i] = networkDispatcher;
                networkDispatcher.start();
            }
        }
    
        /**
         * Stops the cache and network dispatchers.
         */
        public void stop() {
            if (mCacheDispatcher != null) {
                mCacheDispatcher.quit();
            }
            for (int i = 0; i < mDispatchers.length; i++) {
                if (mDispatchers[i] != null) {
                    mDispatchers[i].quit();
                }
            }
        }

    其中可以看到,start函数先调用stop退出mCacheDispatcher和mDispatchers的所有工作线程,确保当前正在运行的派发线程都停止以后,再重新创建并启动派发线程。

    mDispatchers很好理解,就是RequestQueue初始化的网络派发线程池,那mCacheDispatcher是什么呢,字面意思就是缓存调度者(派发器)

    看他构造函数中的四个参数,后两个mCache和mDelivery就是从第一句代码传进来的参数,比较好理解,剩下前面两个参数:mCacheQueue和mNetworkQueue

    在RequestQueue.java中可以找到它两的定义,如下:

        /** 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<?>>();

    PriorityBlockingQueue是java并发包java.util.concurrent提供的,使用PriorityBlockingQueue可以进行任务按优先级同步执行。看看泛型定义成Request可以联想到这两个队列应该是用来存储缓存请求和网络请求的。

    自此volley的第一句代码已经执行完毕,返回一个RequestQueue了,我来自己总结一下第一句代码做了些什么:

    1.第一步是从传入参数context定义好缓存目录cacheDir,包名版本号userAgent,HttpStack协议栈;利用协议栈创建network网络接口;利用缓存目录创建硬盘缓存cache

    2.把network和cache传入RequestQueue创建请求队列,其中经过2步构造函数的重载跳转,新增加了网络派发线程池mDispatchers和应答传递者mDelivery,四个参数实现完成了RequestQueue的初始化工作。

    3.requestqueue初始化完成后,调用start启动请求队列正式工作。其中start先是把requestqueue中的所有mCacheDispatcher和mDispatchers的工作线程退出,并重新加载。两者的创建都需要用到了RequestQueue内部私有成员PriorityBlockingQueue<Request<?>> mCacheQueue 和 PriorityBlockingQueue<Request<?>> mNetworkQueue。

    自于mCacheQueue和mNetworkQueue实际的工作原理,就得分开记录了~

  • 相关阅读:
    What does operator “dot” (.) mean?
    regression and anova
    2014年6月6至7日,杨学明老师《单元测试管理》公开课在深圳市民中心成功举办!
    2014年5月22至23日,杨学明老师《研发多项目管理》在深圳华侨城鸿波酒店成功举办!
    2014年4月25~26日,杨学明老师《产品测试管理高级实务培训》公开课在上海成功举办!
    2014年4月22~23日,杨学明老师《产品测试管理高级实务培训》公开课在深圳成功举办!
    2014年4月18~19日,杨学明老师《软件测试管理》公开课在上海成功举办!
    2014年4月11~12日,杨学明老师《产品测试管理》公开课在北京成功举办!
    2014年3月21~22日,杨学明老师《软件测试管理》公开课在深圳成功举办!
    2014年3月14~15日,杨学明老师软件测试管理公开课在深圳成功举办!
  • 原文地址:https://www.cnblogs.com/zzrblog/p/4179036.html
Copyright © 2011-2022 走看看