Volley源码阅读(0)

来源:互联网 发布:免费取女装淘宝店名 编辑:程序博客网 时间:2024/05/20 14:40

这里写图片描述

在RequestQueue类中

1、首先看add方法

 if (!request.shouldCache()) {            mNetworkQueue.add(request);            return request;        }

在他的add方法中会判断是否需要缓存.shouldCache(),需要则添加到mNetworkQueue网络处理队列,至此返回
否则进入缓存队列处理

synchronized (mWaitingRequests) {            String cacheKey = request.getCacheKey();            if (mWaitingRequests.containsKey(cacheKey)) {                // There is already a request in flight. Queue up.                Queue<Request<?>> stagedRequests = mWaitingRequests.get(cacheKey);                if (stagedRequests == null) {                    stagedRequests = new LinkedList<Request<?>>();                }                stagedRequests.add(request);                mWaitingRequests.put(cacheKey, stagedRequests);                if (VolleyLog.DEBUG) {                    VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);                }            } else {                // Insert 'null' queue for this cacheKey, indicating there is now a request in                // flight.                mWaitingRequests.put(cacheKey, null);                mCacheQueue.add(request);            }            return request;        }

在加入缓存队列前每个请求得到都会判断该请求是否正在执行(flight)判断条件就是请求的cacheKey是否对应 map集合mWaitingRequests

2、再来看finish方法(因为上面的mWaitingRequest在finish方法中被处理了)

```<T> void finish(Request<T> request) {        // Remove from the set of requests currently being processed.        synchronized (mCurrentRequests) {            mCurrentRequests.remove(request);        }        synchronized (mFinishedListeners) {          for (RequestFinishedListener<T> listener : mFinishedListeners) {            listener.onRequestFinished(request);          }        }        if (request.shouldCache()) {            synchronized (mWaitingRequests) {                String cacheKey = request.getCacheKey();                Queue<Request<?>> waitingRequests = mWaitingRequests.remove(cacheKey);                if (waitingRequests != null) {                    if (VolleyLog.DEBUG) {                        VolleyLog.v("Releasing %d waiting requests for cacheKey=%s.",                                waitingRequests.size(), cacheKey);                    }                    // Process all queued up requests. They won't be considered as in flight, but                    // that's not a problem as the cache has been primed by 'request'.                    mCacheQueue.addAll(waitingRequests);                }            }        }```

上面代码中做了这些事:
将请求从mCurrentRequests主队列(存了网络队列和缓存队列)移除了,添加了请求完成监听,如果该请求同时是能被缓存的则把存于mWaitingRequests中的相同请求取出并加入mCacheQueue缓存队列。(个人认为这是为了处理多次相同请求能够依次进行缓存,而HashMap不支持相同键值对存在,所以引入mWaitingRequests)

推测引入mWaitingRequest是为了处理相同请求多次依次处理而作为中间存储空间。

从注释中可以看到

* Called from {@link Request#finish(String)}, indicating that processing of the given request
* has finished.

finish是在Request中的finish被调用的
那么Request中怎么有RequestQueue对象呢?因为Request中有setRequestQueue,在RequestQueue中的add方法一开始就调用了
也就是说每一个被添加到RequestQueue中Request都与RequestQueue绑定了。

3、看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();    }}```

先调用了stop方法,将当前的正在运行的dispatchers全部停掉
再创建了缓存分发线程和网络分发线程

CacheDispatcher()中的参数:mCacheQueue–>缓存请求队列 |
mNetworkQueue–>网络请求队列 |-都是实现Queue接口的PriorityBlockingQueue对象,指针
mCache–>缓存操作对象,默认传入的是DiskBasedCache对象(这里用于读取缓存)
mDelivery–>监听接口传递,是实现了ResponseDelivery的子类ExecutorDelivery的对象
|-它的方法postResponse可以用于绑定Response响应结果给监听器

NetworkDispatcher()中的参数:mNetworkQueue–>网络请求队列
mNetwork–>网络请求对象,能够执行网络请求
mCache–>缓存操作对象,默认传入的是DiskBasedCache对象(这里用于写入缓存)
mDelivery–>监听接口传递,是实现了ResponseDelivery的子类ExecutorDelivery的对象
|-它的方法postResponse可以用于绑定Response响应结果给监听器

4、看cancelAll()、stop()方法:

 /**     * Cancels all requests in this queue for which the given filter applies.     * @param filter The filtering function to use     */    public void cancelAll(RequestFilter filter) {        synchronized (mCurrentRequests) {            for (Request<?> request : mCurrentRequests) {                if (filter.apply(request)) {                    request.cancel();                }            }        }    }

cancelAll()方法用于将当前的mCurrentRequests集合中全部进行标记取消,理论上只能在线程没开启的时候取消

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

stop()方法则是调用线程执行quit()方法,理论上可以停止正在执行缓存和网络任务的线程
@see quit()

    public void quit() {        mQuit = true;        interrupt();    }

quit()方法标记为true,使线程的while循环退出并调用Thread中的interrupt()方法中断线程。

5、看RequestQueue的构造

```RequestQueue的核心构造器:    public RequestQueue(Cache cache, Network network, int threadPoolSize,            ResponseDelivery delivery) {        mCache = cache;        mNetwork = network;        mDispatchers = new NetworkDispatcher[threadPoolSize];        mDelivery = delivery;    }```

传入缓存执行对象,Volley中的newRequestQueue(),
网络请求mNetworkQueue和缓存队列mCacheQueue都是 PriorityBlockingQueue对象 RequestQueue存储请求用的是set集合(HashSet)

其他备注

1、 LinkedList类实现了Queue接口

2、 锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁,代码块中对该对象有一些处理操作。

3、
//得到Android系统的版本
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH

4、TrafficStats.setThreadStatsTag(request.getTrafficStatsTag());
5、Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

6、Request中有个isCancel()方法。取消请求,如果请求已经在进行了则不起作用。这个方法是请求还没执行时有作用。也就是说在线程已经开始run了。

7、Request基类中定义了错误监听,因为子类的错误监听都相同,成功的监听都不同,成功的监听结果有String,Json,Image等。

8、Request中有返回监听,有错误返回监听,成功监听有子类设置,有个接口为ResponseDelivery,用于传递监听的,其子类ExecutorDelivery用于绑定Request及其子类的监听与Response的。
9、BlockingQueue<String> queue = new PriorityBlockingQueue();
这个队列对象相当于指针,对象作为参数传入方法后,改变值会同时在外面被改变;在RequestQueue类中的mNetWorkQueue和mCacheQueue都是这个类型的对象。

//TODO 还有其他的一些关键类再去了解

0 0
原创粉丝点击