6院促、volley 源碼解析之工作流程綜述

文章摘要
1秘血、volley 中的工作線程
2即彪、volley 工作步驟
3紧唱、RequestQueue初始化以及初始化邏輯


附:獲取Volley源代碼
Demos案例源碼:https://github.com/HailouWang/DemosForApi

感悟:

Volley的源代碼真的值得去讀,其中包含了很多非常好的處理邏輯隶校,例如:Volley對其工作流程的架構(gòu)漏益、線程緩存的處理、網(wǎng)絡(luò)請求數(shù)據(jù)的解析以及處理深胳、其中用到的設(shè)計模式等绰疤。

當(dāng)我們明確了volley要解決的開發(fā)痛點后,volley提供了松耦合的架構(gòu)實現(xiàn)舞终,我們可以很方便的在其框架實現(xiàn)內(nèi)轻庆,為其進(jìn)行功能擴(kuò)展。引用設(shè)計模式的一句話:一切為了松耦合的設(shè)計而努力敛劝。

簡介:

volley有兩個主要的民工余爆,CacheDispatcher以及NetworkDispatcher,也是兩個線程夸盟,管理并處理Request任務(wù)蛾方。

volley為了保證大批量的網(wǎng)絡(luò)請求以及數(shù)據(jù)解析不會影響到主線程的用戶交互,使用了很多線程以及線程封裝技巧。包括這里的Cache桩砰。

在用戶發(fā)起網(wǎng)絡(luò)請求后拓春,volley就將用戶的請求,丟到了本文介紹的緩存進(jìn)程亚隅,緩存線程如果沒有能力處理硼莽,就丟給網(wǎng)絡(luò)線程,并告訴它煮纵,老大需要數(shù)據(jù)結(jié)果懂鸵,你趕緊去網(wǎng)絡(luò)上去拿。老大只要結(jié)果醉途,不要過程矾瑰。

主線程很忙,ResponseDelivery負(fù)責(zé)傳遞消息隘擎,伴君如伴虎殴穴,為了防止打擾到主線程的工作,ResponseDelivery也可以有一個線程货葬,在目前的源碼里采幌,ResponseDelivery充分利用Handler的MessageQueue優(yōu)勢,管理并小心的將結(jié)果傳遞給主線程震桶。

1休傍、volley 中,存在三類線程:

  • 1蹲姐、主線程磨取。將獲取的數(shù)據(jù)刷新到UI,發(fā)送網(wǎng)絡(luò)請求等柴墩。
  • 2忙厌、緩存進(jìn)程(Cache Thread)。管理緩存數(shù)據(jù)江咳,主線程的請求逢净,優(yōu)先從主線程中獲取數(shù)據(jù),其次將請求分發(fā)到網(wǎng)絡(luò)中歼指。
  • 3爹土、網(wǎng)絡(luò)線程(Network Thread)。用戶可以制定網(wǎng)絡(luò)線程的數(shù)量踩身,默認(rèn)是4個胀茵。定義了從網(wǎng)絡(luò)獲取數(shù)據(jù)的流程,但不包括網(wǎng)絡(luò)同步邏輯挟阻。這樣子的設(shè)計宰掉,可以更好的釋放線程和網(wǎng)絡(luò)解析邏輯之間的耦合呵哨。
for (int i = 0; i < DEFAULT_NETWORK_THREAD_POOL_SIZE; i++) {
    NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
      mCache, mDelivery);
    mDispatchers[i] = networkDispatcher;
    networkDispatcher.start();
}

2、volley 工作步驟

之前的Demos中發(fā)送一個簡單的請求轨奄、,無論是通過RequestQueue還是通過ImageLoader拒炎,大致的使用步驟是一樣的挪拟,大體包括以下步驟:

  • 2.1、初始化RequestQueue或者ImageLoader击你。
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
  • 2.2玉组、初始化Request
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Display the first 500 characters of the response string.
        mTextView.setText("Response is: "+ response.substring(0,500));
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mTextView.setText("That didn't work!");
    }
});
  • 2.3、 將Request 加入到RequestQueue丁侄。
// Add the request to the RequestQueue.
queue.add(stringRequest);

后兩個步驟惯雳,是對RequestQueue的使用,所以鸿摇,我們將重點放在第一部分石景,即:RequestQueue的創(chuàng)建流程。

3拙吉、RequestQueue初始化

RequestQueue會對Request進(jìn)行管理潮孽,它的作用,更多的是作為一個工具類筷黔,通過add方法往史,將Request分發(fā)給Cache線程以及網(wǎng)絡(luò)線程。

  • 3.1佛舱、首先通過newRequestQueue方法獲得RequestQueue對象椎例。
    public static RequestQueue newRequestQueue(Context context) {
        //1、初始化Network對象请祖。Network的意義是通過performRequest方法解析Request订歪,生成Response對象。
        HttpStack stack;
        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);
        //2损拢、初始化RequestQueue陌粹,共計兩個參數(shù):第一個參數(shù)是Cache緩沖區(qū),可選福压,即:可不緩沖掏秩。
        //第二個參數(shù)是network對象,也是關(guān)系解析網(wǎng)絡(luò)數(shù)據(jù)的主要勞工荆姆。
        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();

        return queue;
    }
Cache類圖
  • 3.2蒙幻、RequestQueue的實例初始化,調(diào)用start后胆筒,線程會跑起來邮破。
    /**
     * Creates the worker pool. Processing will not begin until {@link #start()} is called.
     *創(chuàng)建一個工作池诈豌,非start方法調(diào)用前,不會開始執(zhí)行
     * @param cache A Cache to use for persisting responses to disk
     * 1抒和、緩存者矫渔。將相應(yīng)數(shù)據(jù)持久化到硬盤
     * @param network A Network interface for performing HTTP requests
     * 2、網(wǎng)絡(luò)處理者摧莽。處理HTTP請求的Network 接口
     * @param threadPoolSize Number of network dispatcher threads to create
     * 3庙洼、網(wǎng)絡(luò)請求分發(fā)者。默認(rèn)4個分發(fā)線程池
     * @param delivery A ResponseDelivery interface for posting responses and errors
     * 4镊辕、響應(yīng)傳遞者油够。運行在主線程,傳遞響應(yīng)數(shù)據(jù)征懈,以及錯誤日志信息石咬,實現(xiàn)來自:Handler的封裝
     */
    public RequestQueue(Cache cache, Network network, int threadPoolSize,
            ResponseDelivery delivery) {
        mCache = cache;
        mNetwork = network;
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        mDelivery = delivery;
    }

4、RequestQueue將Request拋給工作線程

RequestQueue通過add方法卖哎,將Request拋給工作線程鬼悠,工作線程包含我們上面說的Cache線程、Network線程棉饶。

//1厦章、將Request加入到mCurrentRequests,因為本工具類還需要管理Request照藻,例如:cancel等袜啃。
// 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.
//2、包裝Request幸缕。為其賦予SequenceNumber
request.setSequence(getSequenceNumber());
request.addMarker("add-to-queue");

// If the request is uncacheable, skip the cache queue and go straight to the network.
//3群发、如果Request不需要緩存,則直接加入到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.
//4发乔、如果請求(Request)不是在等待中(即:mWaitingRequests中)熟妓,那么就先拋給緩沖線程(mCacheQueue)。
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<>();
        }
        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);
    }

緩沖區(qū)(RequestQueue)在獲得Request后栏尚,接著如何處理起愈,請關(guān)注:volley 源碼解析之緩存線程工作流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市译仗,隨后出現(xiàn)的幾起案子抬虽,更是在濱河造成了極大的恐慌,老刑警劉巖纵菌,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阐污,死亡現(xiàn)場離奇詭異,居然都是意外死亡咱圆,警方通過查閱死者的電腦和手機(jī)笛辟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進(jìn)店門功氨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人手幢,你說我怎么就攤上這事捷凄。” “怎么了围来?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵纵势,是天一觀的道長。 經(jīng)常有香客問我管钳,道長,這世上最難降的妖魔是什么软舌? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任才漆,我火速辦了婚禮,結(jié)果婚禮上佛点,老公的妹妹穿的比我還像新娘醇滥。我一直安慰自己,他們只是感情好超营,可當(dāng)我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布鸳玩。 她就那樣靜靜地躺著,像睡著了一般演闭。 火紅的嫁衣襯著肌膚如雪不跟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天米碰,我揣著相機(jī)與錄音窝革,去河邊找鬼。 笑死吕座,一個胖子當(dāng)著我的面吹牛虐译,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吴趴,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼漆诽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锣枝?” 一聲冷哼從身側(cè)響起厢拭,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惊橱,沒想到半個月后蚪腐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡税朴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年回季,在試婚紗的時候發(fā)現(xiàn)自己被綠了家制。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡泡一,死狀恐怖颤殴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鼻忠,我是刑警寧澤涵但,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站帖蔓,受9級特大地震影響矮瘟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜塑娇,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一澈侠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧埋酬,春花似錦哨啃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至珍特,卻和暖如春祝峻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背次坡。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工呼猪, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砸琅。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓宋距,卻偏偏與公主長得像,于是被迫代替她去往敵國和親症脂。 傳聞我的和親對象是個殘疾皇子谚赎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 注:本文轉(zhuǎn)自http://codekk.com/open-source-project-analysis/deta...
    Ten_Minutes閱讀 1,288評論 1 16
  • Volley簡介 Volley 是 Google I/O 2013上發(fā)布的網(wǎng)絡(luò)通信庫,使網(wǎng)絡(luò)通信更快诱篷、更簡單壶唤、更健...
    shenhuniurou閱讀 914評論 0 3
  • Volley已是老牌的網(wǎng)絡(luò)請求庫了(雖然也就3歲不到),雖然是Google官方的庫棕所,但是目前OkHttp才正是大行...
    LeonXtp閱讀 414評論 0 1
  • 在Volley 源碼解析及對 Volley 的擴(kuò)展系列的第一篇文章中闸盔,介紹了一種通過繼承 StringReques...
    lijiankun24閱讀 605評論 0 2
  • 周六作業(yè):短視頻分析訓(xùn)練選擇一個3分鐘內(nèi)的微信短視頻,并深入分析其優(yōu)點與缺點琳省,并嘗試總結(jié)做好一個短視頻需要具備什么...
    神域熊貓閱讀 177評論 0 0