Volley源码学习(一):Volley类,RequestQueue类

来源:互联网 发布:淘宝茜茜家的铺子真假 编辑:程序博客网 时间:2024/05/16 15:50

一.volley的用途

主要用于网络操作,获取数据,并缓存到本地SD卡,有默认4个线程处理网络请求。

二.源码解析

1.volley类:获得RequestQueue,并start

public class Volley {    /** Default on-disk cache directory. */    private static final String DEFAULT_CACHE_DIR = "andbase";    /**     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.     *     * @param context A {@link Context} to use for creating the cache dir.     * @param stack An {@link HttpStack} to use for the network, or null for default.     * @return A started {@link RequestQueue} instance.     */    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {    File cacheDir = null;    if(!AbFileUtil.isCanUseSD()){    cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);}else{cacheDir = new File(AbFileUtil.getCacheDownloadDir(context));}        String userAgent = "andbase/0";    PackageInfo info = AbAppUtil.getPackageInfo(context);        userAgent = info.packageName + "/" + info.versionCode;        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);<span style="white-space:pre"></span>//获得requestQueue        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);        queue.start();        return queue;    }

volley主要方法newRequestQueue(Context,httpStack),context用于生成DiskBasedCache,stack用于生成network.DiskBasedCache是专门管理cache的put,get,将数据写到目标文件夹。network用于网络请求获得response.
注意:sdk>9,网络请求使用HurlStack,内部使用httpconnection。<9使用httpclientstack,内部使用httpclient。httpconnetion API少,bug少,更易扩展。

2.RequestQueue类:

控制中心,处理request,判断后交由CacheQueue或NetworkQueue处理,文件由Cache进行缓存,ResponseDelivery将response传递给request的listener.

主要方法:
方法:start():启动cacheDispatcher和默认4个NetworkDispatcher线程来自动处理request
方法:add(request):添加请求,内部逻辑判断后,将request交由CacheQueue或NetWorkQueue
流程:①mCurrentRequests.add(request)添加request→!request.shouldCache(),不需缓存,就添加到NetworkQueue→判断mWaitingRequests.containsKey(cacheKey)是,mWaitingRequests添加一个stageRequest→
否,mWaitingRequests添加cacheKey,表明正在处理request,同时CacheQueue添加request
方法:finish:结束时从mCurrentRequest里移除,并移除mWaitingRequest的request,如果mWaitingRequest的request不为null,添加到cache里。(为什么?request没处理完被结束掉,mCacheQueue可以继续处理??)
    public RequestQueue(Cache cache, Network network, int threadPoolSize,            ResponseDelivery delivery) {        mCache = cache;       //用于put,get cache文件        mNetwork = network;   //进行网络操作的类,需要传入url        mDispatchers = new NetworkDispatcher[threadPoolSize];  //网络请求分发处理类,是个线程,        mDelivery = delivery;       //将response post给request    }
    public void start() {     //启动cacheDispatcher和默认4个NetworkDispatcher线程来自动处理request        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();        }    }
 public Request add(Request request) {        // Tag the request as belonging to this queue and add it to the set of current requests.        request.setRequestQueue(this);        synchronized (mCurrentRequests) {            mCurrentRequests.add(request);        }        // Process requests in the order they are added.        request.setSequence(getSequenceNumber());        request.addMarker("add-to-queue");        // If the request is uncacheable, skip the cache queue and go straight to the network.        if (!request.shouldCache()) {            mNetworkQueue.add(request);            return request;        }        // Insert request into stage if there's already a request with the same cache key in flight.        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;        }    }






0 0
原创粉丝点击