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实际的工作原理,就得分开记录了~

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。