Glide源碼分析(四)蜻牢,DecodeJob執(zhí)行過程

開始本文之前烤咧,DecodeJob它實現(xiàn)了Runnable接口偏陪,敏感的朋友可能已經(jīng)意識到,加載代碼的入口就在這里煮嫌,會在一個新的線程中去加載資源笛谦。DecodeJob這個類的代碼非常多,主要有以下幾個重要的點昌阿。

  1. 封裝一些從上面?zhèn)鬟^來的參數(shù)信息饥脑,不知道是否還有印象,我們的glide大部分信息是通過前面RequestBuilder中得到的懦冰。這里灶轰,它內(nèi)部構(gòu)造了一個DecodeHelper類,封裝了大部分的請求信息刷钢。

  2. 數(shù)據(jù)加載模塊DataFetcher與ModelLoader笋颤,以及加載數(shù)據(jù)的回調(diào)接口。詳細(xì)參考數(shù)據(jù)加載DataFetcher與ModelLoader結(jié)構(gòu)内地。DataFetcher中定義了加載數(shù)據(jù)的接口伴澄,其子類很多,比如從網(wǎng)絡(luò)加載或者是文件加載阱缓,均是由其子類具體實現(xiàn)非凌。

  3. DataFetcherGenerator使用已注冊的{@link com.bumptech.glide.load.model.ModelLoader ModelLoaders}和一個模型生成一系列{@link com.bumptech.glide.load.data.DataFetcher DataFetchers}。在DataFetcherGenerator中茬祷,通過DecodeHelper類清焕,我們還可以拿到ModelLoader的信息,而通過ModelLoader我們可以得到LoadData的數(shù)據(jù)結(jié)構(gòu)祭犯,從而取得對應(yīng)的DataFetcher秸妥,進(jìn)而去獲取數(shù)據(jù)。DataFetcherGenerator結(jié)構(gòu)沃粗。

DecodeJob其他詳細(xì)信息可以參考DecodeJob結(jié)構(gòu)粥惧。
加載一個資源最終到一個ImageView上面的大致流程圖如下:

sequence_engine.png
  1. SingleRequest的onSizeReady方法啟動Engine的load方法,同時將ResourceCallback傳入最盅。這個ResourceCallback最終會調(diào)用相關(guān)的Target突雪,完成資源的最終渲染。
  2. Engine的load方法,它里面會根據(jù)條件判斷涡贱,這里我們討論是本地完全沒有緩存的情況咏删,這個時候,load中问词,會創(chuàng)建EngineJob與DecodeJob督函,DecodeJob是真正開啟線程加載數(shù)據(jù)的地方,EngineJob負(fù)責(zé)調(diào)度DecodeJob以及和上層模塊通信,它們是一個一對一的關(guān)系辰狡。EngineJob中實現(xiàn)了DecodeJob.Callback用于監(jiān)聽下面數(shù)據(jù)加載的狀態(tài)锋叨,同時在EngineJon中維護(hù)了一系列的從Engine#load方法中傳入的ResourceCallback信息,用戶在監(jiān)聽到數(shù)據(jù)加載結(jié)果之后宛篇,通知上層模塊娃磺,也就是SingleRequest。隨之觸發(fā)啟動DecodeJob叫倍,開始任務(wù)偷卧。
  3. DecodeJob的run方法得到執(zhí)行,在run方法里段标,它會構(gòu)造一個DataFetcherGenerator,run方法里面會觸發(fā)DataFetcherGenerator的startNext方法涯冠,同時通過設(shè)置到DataFetcherGenerator的FetcherReadyCallback接口,監(jiān)聽數(shù)據(jù)的獲取狀態(tài)逼庞,再將結(jié)果上報至EngineJob中(它實現(xiàn)了DecodeJob.Callback接口)蛇更。
  4. DataFetcherGenerator的startNext,generator會從DecodeHelper中去獲取當(dāng)前的ModelLoader信息,構(gòu)造出一個LoadData結(jié)構(gòu)類型的數(shù)據(jù)赛糟,得到相應(yīng)的DataFetcher對象派任。DataFetcherGenerator子類實現(xiàn)了DataFetcher.DataCallback接口。它是用于監(jiān)聽DataFetcher#loadData結(jié)果璧南。
  5. DataFetcher#loadData完成之后掌逛,會將執(zhí)行結(jié)果上報至
    DataFetcherGenerator,因為其實現(xiàn)了DataFetcher.DataCallback接口司倚,在其實現(xiàn)上面豆混,回繼續(xù)回調(diào)其成員變量執(zhí)行的FetcherReadyCallback中的方法,而此時动知,F(xiàn)etcherReadyCallback實現(xiàn)類正是DecodeJob皿伺,因此,代碼繼續(xù)執(zhí)行到DecodeJob的回調(diào)方法中盒粮,我們先至考慮簡單的情況鸵鸥,忽略線程之間的切換。
  6. 回到DecodeJob的FetcherReadyCallback的實現(xiàn)中丹皱,它接下來會繼續(xù)回調(diào)設(shè)置在其成員變量的類型為DecodeJob.Callback引用妒穴,而正是EngineJob實現(xiàn)了這個Callback,因此,代碼流程進(jìn)一步轉(zhuǎn)換給到EngineJob中摊崭。
  7. EngineJob實現(xiàn)了DecodeJob.Callback讼油,此時還沒有做線程切換,是處于和DecodeJob#run方法相同的線程呢簸,此時汁讼,EngineJob中利用Handler機制淆攻,將繼續(xù)分發(fā)加載到的數(shù)據(jù)的結(jié)果,觸發(fā)其handleResultOnMainThread方法嘿架。見名思義,此時已經(jīng)切換到了主線程啸箫。
  8. EngineJob#handleResultOnMainThread方法中耸彪,會回調(diào)在上面講到的,它中維護(hù)了一系列的從Engine#load方法中傳入的ResourceCallback信息忘苛,所以這里會對它們繼續(xù)進(jìn)行回調(diào)蝉娜。
  9. ResourceCallback,它的實現(xiàn)是在SingleRequest中扎唾,在它的實現(xiàn)中召川,會將結(jié)果交給相應(yīng)的Target去處理,而我們的ImageView渲染資源正是由這些Target在調(diào)度胸遇。所以荧呐,最終資源就成功的顯示到了控件上面。

總體來說纸镊,宏觀上代碼邏輯還是很清晰的倍阐,一次加載過程,會創(chuàng)建一個SingleRequest逗威,調(diào)用全局的加載引擎Engine峰搪,去創(chuàng)建一對EngineJob與DecodeJob,最后在DecodeJob中凯旭,根據(jù)DataFetcherGenerator獲取到相應(yīng)的DataFetcher概耻,執(zhí)行數(shù)據(jù)的加載。成功之后罐呼,一步步回調(diào)回去鞠柄。先是DataFetcher到DataFetcherGenerator,再是DataFetcherGenerator到DecodeJob,再是從DecodeJob到EngineJob,進(jìn)而在EngineJob中做線程切換,回到主線程弄贿,將結(jié)果回調(diào)至SingeRequest春锋,再由SingleRequest中保存的Target引用通知到對應(yīng)的控件,完成資源的渲染差凹。同時EngineJob也會告知Engine期奔,此次job已經(jīng)加載完成,是由EngineJobListener完成的危尿。大致就是一個鏈?zhǔn)降腃allback回調(diào)過程呐萌。后面我會在代碼上,根據(jù)這個大綱谊娇,詳細(xì)分析一次從網(wǎng)絡(luò)加載肺孤,并緩存到磁盤的詳細(xì)過程。

下一篇 Glide源碼分析(五),EngineJob與DecodeJob代碼詳細(xì)加載過程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赠堵,一起剝皮案震驚了整個濱河市小渊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茫叭,老刑警劉巖酬屉,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異揍愁,居然都是意外死亡呐萨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門莽囤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谬擦,“玉大人,你說我怎么就攤上這事朽缎〔以叮” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵饵沧,是天一觀的道長锨络。 經(jīng)常有香客問我,道長狼牺,這世上最難降的妖魔是什么羡儿? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮是钥,結(jié)果婚禮上掠归,老公的妹妹穿的比我還像新娘。我一直安慰自己悄泥,他們只是感情好虏冻,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弹囚,像睡著了一般厨相。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸥鹉,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天蛮穿,我揣著相機與錄音,去河邊找鬼毁渗。 笑死践磅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灸异。 我是一名探鬼主播府适,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼羔飞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了檐春?” 一聲冷哼從身側(cè)響起逻淌,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喇聊,沒想到半個月后恍风,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡誓篱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年疑枯,在試婚紗的時候發(fā)現(xiàn)自己被綠了朴恳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡奔浅,死狀恐怖摆屯,靈堂內(nèi)的尸體忽然破棺而出邻遏,到底是詐尸還是另有隱情,我是刑警寧澤虐骑,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布准验,位于F島的核電站,受9級特大地震影響廷没,放射性物質(zhì)發(fā)生泄漏糊饱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一颠黎、第九天 我趴在偏房一處隱蔽的房頂上張望另锋。 院中可真熱鬧,春花似錦狭归、人聲如沸夭坪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽室梅。三九已至,卻和暖如春疚宇,著一層夾襖步出監(jiān)牢的瞬間亡鼠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工灰嫉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拆宛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓讼撒,卻偏偏與公主長得像浑厚,于是被迫代替她去往敵國和親股耽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

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