7昆婿、volley 源碼解析之緩存線程工作流程

文章摘要
1柑爸、volley 緩存線程運行流程
2、volley 實現(xiàn)分解步驟


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

簡介:

volley有兩個主要的民工,CacheDispatcher以及NetworkDispatcher骇窍,也是兩個線程瓜晤,管理并處理Request任務(wù)。

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

在用戶發(fā)起網(wǎng)絡(luò)請求后嘲恍,volley就將用戶的請求足画,丟到了本文介紹的緩存進程,緩存線程如果沒有能力處理佃牛,就丟給網(wǎng)絡(luò)線程锌云,并告訴它,老大需要數(shù)據(jù)結(jié)果吁脱,你趕緊去網(wǎng)絡(luò)上去拿桑涎。老大只要結(jié)果,不要過程兼贡。

主線程很忙攻冷,ResponseDelivery負責(zé)傳遞消息,伴君如伴虎遍希,為了防止打擾到主線程的工作等曼,ResponseDelivery也可以有一個線程,在目前的源碼里凿蒜,ResponseDelivery充分利用Handler的MessageQueue優(yōu)勢禁谦,管理并小心的將結(jié)果傳遞給主線程。

那么废封,本文就來介紹下緩存線程的工作原理:

一州泊、CacheDispatcher線程

  • 1、Volley中有三個線程漂洋,CacheDispatcher是其中的緩存線程遥皂。

  • 2、CacheDispatcher緩沖線程的目的是在緩沖池中刽漂,執(zhí)行分流演训,將Request請求分發(fā)出去。
    線程循環(huán)運行贝咙,線程原料來自mCacheQueue样悟,在主線程可通過RequestQueue.add方法將請求加入mCacheQueue。

  • 3、可以將工作流程簡單歸納為以下幾步:

    • 1窟她、線程循環(huán)運行陈症,線程原料來自mCacheQueue。
    • 2礁苗、優(yōu)先從緩沖區(qū)獲得數(shù)據(jù),如果緩存區(qū)中存在數(shù)據(jù)徙缴,則直接返回數(shù)據(jù)給主線程试伙。
    • 3、如果緩存區(qū)【沒有命中數(shù)據(jù)】或者【緩存數(shù)據(jù)過期】于样,則將請求(Request)分發(fā)給NetworkDispatcher(網(wǎng)絡(luò)線程)疏叨,網(wǎng)絡(luò)線程會重新同步數(shù)據(jù)。

附:流程圖

  • Volley Cache Thread流程圖.png

二穿剖、實現(xiàn)分析

1蚤蔓、線程循環(huán)運行,獲得Request對象

while (true) {
  try {
    // Get a request from the cache triage queue, blocking until
    // at least one is available.
    //1糊余、hlwang:CacheDispatcher原料來自mCacheQueue秀又,第一步,獲得Request
    final Request<?> request = mCacheQueue.take();
    request.addMarker("cache-queue-take");
    ... ...
  }
}

2贬芥、如果Request被用戶取消了吐辙,則不再需要繼續(xù)執(zhí)行了

// If the request has been canceled, don't bother dispatching it.
//2、hlwang:如果request已取消蘸劈,已經(jīng)不需要繼續(xù)了
if (request.isCanceled()) {
    request.finish("cache-discard-canceled");
    continue;
}

3昏苏、優(yōu)先檢查緩存區(qū),如果數(shù)據(jù)沒有命中(即:數(shù)據(jù)不存在)威沫,則交給Network線程去同步數(shù)據(jù)

// Attempt to retrieve this item from cache.
//3贤惯、hlwang:如果在緩存中,不存在數(shù)據(jù)棒掠,說明是新數(shù)據(jù)孵构,則:交給mNetworkQueue去同步新數(shù)據(jù)。
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) {
    request.addMarker("cache-miss");
    // Cache miss; send off to the network dispatcher.
    mNetworkQueue.put(request);
    continue;
}

4烟很、如果緩存數(shù)據(jù)過期了浦译,依舊交給Network線程去同步數(shù)據(jù)

// If it is completely expired, just send it to the network.
//4、hlwang:如果緩存過期溯职,那么說明數(shù)據(jù)太舊了精盅,交給mNetworkQueue去同步新數(shù)據(jù)。
if (entry.isExpired()) {
    request.addMarker("cache-hit-expired");
    request.setCacheEntry(entry);
    mNetworkQueue.put(request);
    continue;
}

5谜酒、緩存的數(shù)據(jù)被命中叹俏,則解析緩存數(shù)據(jù),構(gòu)建Response對象

// We have a cache hit; parse its data for delivery back to the request.
//5僻族、wanghailu:我們命中了一條緩存數(shù)據(jù)(w找到了一個保質(zhì)期內(nèi)的緩存hl)粘驰,解析數(shù)據(jù)并構(gòu)建響應(yīng)對象Response屡谐。
request.addMarker("cache-hit");
Response<?> response = request.parseNetworkResponse(
        new NetworkResponse(entry.data, entry.responseHeaders));
request.addMarker("cache-hit-parsed");

6、如果緩存數(shù)據(jù)蝌数,不需要刷新愕掏,則將響應(yīng)數(shù)據(jù),通過Delivery回調(diào)給用戶

if (!entry.refreshNeeded()) {
    // Completely unexpired cache hit. Just deliver the response.
    //6顶伞、如果entry數(shù)據(jù)不需要刷新饵撑,則使用mDelivery將響應(yīng)傳遞出去
    mDelivery.postResponse(request, response);
} 

7、緩存的數(shù)據(jù)需要再次更新唆貌,那么現(xiàn)將緩存數(shù)據(jù)返回給用戶滑潘,接著通過主線程發(fā)起同步數(shù)據(jù)請求

    // Soft-expired cache hit. We can deliver the cached response,
    // but we need to also send the request to the network for
    // refreshing.
    //7、雖然被緩存命中锨咙,但數(shù)據(jù)輕微過期语卤。我們可以將緩存響應(yīng)數(shù)據(jù)傳遞分發(fā),
    //但我們同樣需要將請求發(fā)送到mNetworkQueue去刷新酪刀、更新粹舵。
    request.addMarker("cache-hit-refresh-needed");
    request.setCacheEntry(entry);

    // Mark the response as intermediate.
    //7.1、更新response狀態(tài)為  媒介
    response.intermediate = true;

    // Post the intermediate response back to the user and have
    // the delivery then forward the request along to the network.
    //7.2骂倘、主線程分發(fā)
    mDelivery.postResponse(request, response, new Runnable() {
        @Override
        public void run() {
            try {
                mNetworkQueue.put(request);
            } catch (InterruptedException e) {
                // Not much we can do about this.
            }
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末齐婴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子稠茂,更是在濱河造成了極大的恐慌柠偶,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睬关,死亡現(xiàn)場離奇詭異诱担,居然都是意外死亡,警方通過查閱死者的電腦和手機电爹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門蔫仙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丐箩,你說我怎么就攤上這事摇邦。” “怎么了屎勘?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵施籍,是天一觀的道長。 經(jīng)常有香客問我概漱,道長丑慎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮竿裂,結(jié)果婚禮上玉吁,老公的妹妹穿的比我還像新娘。我一直安慰自己腻异,他們只是感情好进副,可當(dāng)我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悔常,像睡著了一般影斑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上这嚣,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天鸥昏,我揣著相機與錄音塞俱,去河邊找鬼姐帚。 笑死,一個胖子當(dāng)著我的面吹牛障涯,可吹牛的內(nèi)容都是我干的罐旗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼唯蝶,長吁一口氣:“原來是場噩夢啊……” “哼九秀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起粘我,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤鼓蜒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后征字,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體都弹,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年匙姜,在試婚紗的時候發(fā)現(xiàn)自己被綠了畅厢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡氮昧,死狀恐怖框杜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袖肥,我是刑警寧澤咪辱,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站椎组,受9級特大地震影響梧乘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一选调、第九天 我趴在偏房一處隱蔽的房頂上張望夹供。 院中可真熱鬧,春花似錦仁堪、人聲如沸哮洽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸟辅。三九已至,卻和暖如春莺葫,著一層夾襖步出監(jiān)牢的瞬間匪凉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工捺檬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留再层,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓堡纬,卻偏偏與公主長得像聂受,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子烤镐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,562評論 2 349

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