public RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());html
一切都從這句代碼開始。。。java
跟着newRequestQueue(Context)到Volley類中android
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()了ide
看看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的全部工做線程,確保當前正在運行的派發線程都中止之後,再從新建立並啓動派發線程。oop
mDispatchers很好理解,就是RequestQueue初始化的網絡派發線程池,那mCacheDispatcher是什麼呢,字面意思就是緩存調度者(派發器)post
看他構造函數中的四個參數,後兩個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實際的工做原理,就得分開記錄了~