- 本文章所使用的 Glide 源碼版本:4.11.0
源碼解析
- 在講源碼之前,我們先復(fù)習(xí)一下 Glide 的用法
主要分成三部曲:傳入 Activity 或者 Fragment佩抹、傳入圖片地址儡陨、傳入目標(biāo)的 ImageView
我們先講講 Glide 的生命周期控制牢撼,也就是 Glide.with 方法蜈首,讓我們簡單看一下里面的源碼
我們可以看到者娱,Glide.with 復(fù)寫了多個(gè)不同參的方法绪颖,那么問題來了秽荤,這些方法有什么不一樣,Glide 又拿它們做了什么事柠横?
帶著這個(gè)疑問窃款,我們先進(jìn)入 Glide.with(FragmentActivity activity) 的源碼里面看看
- 通過查看這幾段源碼,我們可以得出一個(gè)結(jié)論滓鸠,Glide 拿到 FragmentActivity 的用處是為了在 Activity 里面創(chuàng)建一個(gè) Fragment雁乡,那么問題又來了,它創(chuàng)建 Fragment 是要做什么事糜俗?接下來讓我們繼續(xù)追蹤一下源碼踱稍。
- 看到這里,我想大多數(shù)人的想法跟我一樣悠抹,想看這個(gè) Fragment 到底長啥樣珠月?
- 通過搜索關(guān)鍵字,我們基本可以斷定這個(gè)是一個(gè)無界面的 Fragment楔敌,也可以認(rèn)為是一個(gè)透明的 Fragment啤挎,那么 Glide 到底是想做什么?
- 接下來讓我們把目光放到一個(gè)類上面,ActivityFragmentLifecycle庆聘,光看名字就知道這個(gè)是我們要講的主角之一:生命周期管理胜臊,接下來我們看看這個(gè)類在 Fragment 里面做了什么事
那么問題又來了,Glide 這樣做的目的又是什么伙判?是為了解決什么問題而做的象对?
這個(gè)問題非常值得我們?nèi)ニ伎迹紫任覀円姥绺В珿lide 是通過網(wǎng)絡(luò)請(qǐng)求獲取圖片的資源勒魔,網(wǎng)絡(luò)請(qǐng)求是異步的,也就是必須在子線程中菇曲,而 Activity 是運(yùn)行在主線程中冠绢,正常的情況是 Glide 請(qǐng)求完畢之后 Activity 再銷毀,但是這個(gè)并不能代表所有的請(qǐng)求都會(huì)按照這個(gè)邏輯來執(zhí)行常潮,往往是 Glide 還沒有請(qǐng)求完畢 Activity 已經(jīng)銷毀了這種情況也非常常見弟胀,為了避免這種情況,我們必須知道 Activity 什么時(shí)候銷毀蕊玷,然后趕在 Activity 銷毀之前把網(wǎng)絡(luò)請(qǐng)求取消邮利。
這個(gè)時(shí)候 Fragment 發(fā)揮了很大的作用,我們都知道 Fragment 是依附于 Activity垃帅,同時(shí)這兩者的生命周期是綁定在一起的延届,Glide 通過 Fragment 的生命周期就能知道 Activity 的生命周期。
那么問題又來了贸诚,剛剛 Glide.with 有很多重載方法方庭,萬一它傳入的不是 FragmentActivity,而是其他類型的對(duì)象酱固,那么 Glide 又會(huì)怎么處理呢械念?
我就是不給你傳入 FragmentActivity,而是直接傳入 Activity运悲,讓 Glide 創(chuàng)建不了 Fragment 對(duì)象龄减,這樣它就監(jiān)聽不到 Activity 的生命周期了
接下來讓我們看看 Glide 應(yīng)對(duì) Activity 對(duì)象會(huì)做什么不一樣的處理?
看到這里班眯,我們要糾正一個(gè)誤區(qū)希停,不是一定要 FragmentActivity 才能創(chuàng)建 Fragment,其實(shí) Activity 對(duì)象也是可以的署隘,只不過這個(gè)是 Android 3.0 之后的特性
app.Fragment宠能、support.Fragment 的思想和用法和 Activity 和 Fragment Activity 大同小異,這里直接略過
再來跟大家講講 Fragment磁餐,它又是怎么監(jiān)聽生命周期的
看到這里违崇,我們沒必須要繼續(xù)往下看了,還是原來的配方,還是熟悉的味道
接下來讓我們看看 Context 參數(shù)的 Glide.with 方法
- 分析上面的源碼羞延,我們可以知道渣淳,你如果給 Glide 傳入的是一個(gè) Context 對(duì)象,它會(huì)自動(dòng)推導(dǎo) Context 的類型伴箩,究竟是 FragmentActivity 呢還是 Activity 呢水由,如果兩種都不是呢?萬一是 Application 的 Context 呢赛蔫?接下來繼續(xù)看源碼
- 看到這段源碼,我們又發(fā)現(xiàn)了一個(gè) Lifecycle 類泥张,只不過這次跟我們之前看到的 ActivityFragmentLifecycle 類不一樣呵恢,因?yàn)樗鼡Q了一個(gè)馬甲:ApplicationLifecycle
- 那么又問題來了,它和 ActivityFragmentLifecycle 有什么區(qū)別媚创?
讓我們?cè)倩仡櫼幌逻@個(gè)類渗钉,經(jīng)過比對(duì)不難發(fā)現(xiàn),ApplicationLifecycle 類沒有生命周期之類的方法回調(diào)
所以到這里钞钙,我們也不難斷定鳄橘,當(dāng)我們傳入的 Context 對(duì)象經(jīng)過推導(dǎo)之后不是 Activity 或者 FragmentActivity 對(duì)象,那么 Glide 會(huì)把這個(gè)請(qǐng)求當(dāng)做一個(gè)全局請(qǐng)求芒炼,何為全局請(qǐng)求瘫怜,請(qǐng)求的生命周期和應(yīng)用的生命周期保持一致,只要應(yīng)用不被殺死本刽,那么這個(gè)網(wǎng)絡(luò)請(qǐng)求在請(qǐng)求完畢之前就不會(huì)消失鲸湃。
總結(jié)
- Glide 請(qǐng)求生命周期主要利用一個(gè)無界面的 Fragment,然后綁定到 Activity / Fragment 上面子寓,由此來感知 Activity / Fragment 的生命周期暗挑,從而趕在 Activity / Fragment 對(duì)象銷毀之前把網(wǎng)絡(luò)請(qǐng)求移除掉,另外如果我們傳入的 Context 對(duì)象不是 Activity / Fragment斜友,Glide 會(huì)默認(rèn)將這個(gè)網(wǎng)絡(luò)請(qǐng)求作為一個(gè)全局請(qǐng)求炸裆,這樣就完成了 Glide 對(duì)網(wǎng)絡(luò)請(qǐng)求的生命周期控制。