Android.Volley的解讀:初始接觸volley

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實際的工做原理,就得分開記錄了~

相關文章
相關標籤/搜索