Glide 架構設計藝術

2021-12-09 code小生
code小生,一個專注 Android 領域的技術平臺

作者:低情商的大仙
連結:https://www.jianshu.com/p/5c8ce241199e
聲明:本文已獲低情商的大仙授權發表,轉發等請聯繫原作者授權

自從Android誕生以來,Bitmap的管理就一直是大問題,為了更好的管理它,不同的圖片加載框架不斷的被推出,從剛開始的ImageLoader,到Picasso,再到現在的Fresco和Glide,可謂百花齊放。然而前兩者現在都已經不再維護了,同時我們公司的項目目前也已經從Fresco切換到Glide了,之前之所以用Fresco是因為他在Android5.0以下系統中能從native層「偷」內存,但後面由於Android對於Bitmap內存管理方式的改變,這個功能不再生效,相比於Glide來說,Fresco就顯得侵入性太強,而且可擴展性沒有glide強。而Glide之所以擴展性如此強,就在於它 優秀的架構設計 ,這也是我們今天要討論的。

1. 總體架構

首先我們看下Glide總體架構圖:

glide總體架構圖

從架構圖上,我們可以看出,glide並沒有著眼於bitmap,而是進行了高度的抽象,所以我們不應該將glide看成一個圖片加載框架,而是一個資源從不同形態之間轉換的框架,從url到bitmap只是其中一種,所以我們不難理解glide甚至能從視頻加載第一幀,因為它沒有對輸入類型做任何限制,都是統一抽象成的Request。

從Request到Data的設計——資源加載模塊設計
首先我們看下總體過程:

glide從Request到Data.png

這裡以從url到inputstream二進位流為例,之所以這裡有三條分路,這和glide的緩存策略有關。首先有一點要澄清,這裡從Request到Data其實是跳過了內存緩存的介紹,畢竟如果內存中已有bitmap緩存,我們直接取用就可以了,無需這麼麻煩(詳細的緩存方案後續文章會介紹)。因此,這裡有三條路徑主要是磁碟緩存和網絡緩存,而磁碟緩存有兩種:

2.1 Request是如何被加載的

由於glide的這種高度抽象,現在我們面臨著一個問題:如此多類型的Request和如此多的Data,具體怎麼去加載它呢?比如說Request有url、uri、File、資源id、視頻等等,不同的Request肯定有不同的加載方式,同一個Request既可能從網絡加載,也可能從磁碟加載,可能性太多,那麼我們怎麼去加載呢?if-else去判斷嗎?一個優秀的框架肯定不會幹這種low到爆的事。這裡我們介紹一些新的角色:

ModelLoader類圖.png

這裡,針對每一種Request,我們都有對應的ModelLoader,當一個Request進來時,我們可以遍歷所有的ModelLoader,通過handles()方法判斷這個ModelLoader能否處理這種Request,這樣我們就能解決第一個問題,即不同的Request如何管理加載,有了ModelLoader機制,如果我們想增加一種Request,我們只要開發對應的ModelLoader即可。

有了ModelLoader,其實是不夠的,它只是用來判斷這個Request是否能否處理,為了能真正的加載請求,Glide引入了DataFetcher,不同的方式對應一個不同的DataFetcher,兩者職責分離,這是因為同一種Request其實有很多加載方式,比如從網絡加載,從磁碟加載等等,非常複雜,所以這裡獨立出一個DataFetcher。其中LoadData只是對DataFetcher的一種包裝,多包含了一些信息而已。

2.2 小結

現在,我們根據傳入的請求具體類型(比如url還是file還是字節數組),通過遍歷所有的ModelLoader判斷該ModelLoader能否處理這種請求,然後用該ModelLoader中的DataFetcher去具體加載這個請求。

3. 從Data到Resource的設計——解碼和轉碼模塊設計

有了ModelLoader和DataFetcher機制,Glide已經能方便的將一個原始請求從不同的地方加載到內存中了,這個時候這份數據還只是單純的二進位數據(攜帶了格式數據)而已,我們稱其為Data,現在需要進行解碼過程,剔除原始的格式信息,然後拿原始信息重新編碼,將其轉化成不同的格式,比如將一個jpg先解碼然後轉碼成Bitmap,或者轉碼成Gif,解碼以及轉碼後的數據我們稱其為Resource。現在面臨的問題還是一樣的:

由於框架的設計決定了需要解碼的格式是不定的,要轉碼的格式也是不定的,如何高效的組織這個過程呢?

這個和Request被加載的過程類似,這裡採用的是模板方法設計模式:

解碼轉碼類圖.png

可以看到,這裡我們能從Registry中獲取所有的ResourceDecoder和ResourceTranscoder,然後判斷哪個解碼器或轉碼器適合當前格式,直接調用相關的decode和transcode方法就可以了。

以這種方式,我們能隨意擴展不同格式的解碼和轉碼了。

4. 從Resource到Resource的設計——資源變換操作

資源解碼並轉碼後,由於某些特殊的需求,我們是不能直接使用的,比如有圓角需求,透明度需求等等,完成這步轉換的,就是Transformation。由於這一步轉換是可選的,和上面兩步都不同必須進過的步驟不同,這裡的Transformation就不能存在一個地方主動去取,必須是得構建這整個流程的時候指定使用哪個Transformation,這裡沒有什麼複雜的架構,大家了解下Transformation的大致情況即可:

Transformation類圖一覽.png5. 從Resource到顯示在Target上的設計——資源顯示操作

現在我們走到了最後一步,需要將符合條件的Resource顯示在指定的Target上,當然具體如何顯示細節本文不討論,我們主要關注的是顯示時候的動畫操作,也就是經過Transition的 transition()。這一步和上面一步類似,是否需要使用Transition和使用哪個Transition都是由請求時用戶決定的,因此這裡也沒有複雜架構,大家看下Transition的組成即可:

Transition.png6. 總結

其實從總體架構上來說,Glide的設計無疑是非常完美的,每一個步驟都是面對接口編程,可以隨意新增或修改其中的某一步,擴展性非常強,這雖然讓架構變的更加複雜,但這點代價是值得的。以這個架構來說,只要Android不死,Glide都能一直用下去。

最後,本文只是簡單的給大家一個Glide的大致流程,每個流程是怎麼回事,讓大家有個概念,甚至連最複雜的緩存都沒提到,更不用說每一步的具體流程了,針對這些,我將會繼續寫一系列的文章,希望能將Glide說清楚。

最後的最後,文章都是我個人的理解,如果有錯誤,懇請大家指正!

推薦閱讀
Android 基於 glide 4.0 封裝圖片加載庫
Android 框架思考--工具類設計(Glide、Picasso切換實現)

相關焦點

  • Android 架構之Glide源碼解讀(上)
    super InputStream> callback) {    long startTime = LogTime.getLogTime();    try {      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
  • 跑鞋評測:adidas supernova glide boost跑鞋
    adidas supernova glide boost評測 adidas supernova glide boost評測  開箱初體驗:  隨著adidas全面啟動Boostadidas supernova glide boost評測   細節亮點:  依舊是內靴設計,依舊前掌馬牌橡膠植入
  • 戴森Omni-glide萬向吸塵器發布 顛覆設計滿足小空間清潔市場需求
    戴森今日推出專為緊湊居住空間打造的戴森Omni-glide萬向吸塵器,顛覆傳統的單向吸塵清潔方式,輕便直線機身設計配合點按式電源開關, 搭配首款萬向軟絨滾筒吸頭,為都市年輕人帶來全新的吸塵體驗。
  • Android 框架思考--工具類設計(Glide、Picasso切換實現)
    、Fresco 或者 volley 等圖片加載庫,所以在設計圖片加載邏輯時需要兼容這些可能變動的需求。工廠模式在使用時關注功能有哪些,具體功能實現由具體的特定工廠(glide、Picasso等)來實現。
  • Android Glide的三個坑
    這篇文章,專門吐槽下glide的三點不合理設計(至少個人認為不合理)吐槽1:Bitmap recycle 相信有不少項目,在線上環境,都有碰到類似的崩潰吧java.lang.RuntimeException: Canvas
  • 戴森Omni-glide萬向吸塵器:全面轉變你的清潔方式
    今日,戴森Omni-glide萬向吸塵器於上海重磅發布。作為戴森迄今最靈活、最輕的吸塵器,戴森Omni-glide萬向吸塵器顛覆了傳統單向吸塵清潔方式,在使用戴森首款萬向軟絨滾筒吸頭的同時,採用了全新的直線機身設計配合點按式電源開關,全方位地轉變你的清潔方式。
  • 戴森Omni-glide萬向吸塵器動手玩:再小的蝸居也能幹淨利落
    戴森似乎聽到了年輕人的呼聲,在「史上最輕」的戴森 Digital Slim 輕量無繩吸塵器之後,推出了 Omni-glide「萬向吸塵器」。除了更加輕便外,戴森 Omni-glide 萬向吸塵器重塑了吸頭設計,戴森首款萬向軟絨滾筒吸頭突破了傳統的單向清潔方式,實現了穩定順滑的萬向除塵,讓清潔省時省力,為居住在緊湊多元空間中的年輕人的日常清潔減負。
  • 戴森發布Omni-glide萬向吸塵器,可能是最靈活的吸塵器
    如果仔細看了官方的圖片可以發現,這次 Omni-glide 萬向吸塵器相比過去變化最大的一點就是捨棄了傳統的槍式握柄,而是改為了上下完全貫通的直線設計,將氣旋、馬達、濾網和手柄放在了一條直線上。這樣設計的好處在哪?根據官方介紹,這種設計讓氣流理論上得以直線通過,減少了氣流的損耗,所以塵氣分離的表現也會變得更好一些。
  • 戴森Omni-glide 吸塵器首發體驗:吸塵器裡的「火弩箭」
    如果說傳統吸塵器就像平板膠棉拖把那樣「直來直去」,那麼 Omni-glide 就如同老式拖把一般靈活,可以按照你的想法任意走位。輕,是靈活的前提。戴森重新設計了整個吸塵器的結構,Omni-glide 整機只有 1.9kg,主機 1.07kg,是整個吸塵器家族裡最嬌小的存在。
  • 全新清潔方式來襲,戴森Omni-glide萬向吸塵器國內首發
    作為戴森迄今最靈活、最輕的吸塵器,戴森Omni-glide萬向吸塵器顛覆了傳統單向吸塵清潔方式,在使用戴森首款萬向軟絨滾筒吸頭的同時,採用了全新的直線機身設計配合點按式電源開關,全方位地轉變你的清潔方式。針對現代都市緊湊的生活空間和複雜的家居布局,戴森Omni-glide萬向吸塵器可在不挪動地面障礙物的情況下實現萬向清潔,並可讓你自由變換手持姿勢,深入打掃家具底部及縫隙等狹小空間。
  • 戴森Omni-glide評測:萬向吸塵器如何解鎖清潔新姿勢
    直到看到戴森前不久剛剛發布的萬向吸塵器 Omni-glide,給人眼前一亮的感覺。它也許談不上太多顛覆式的技術,但是由於採用了完全不同於此前V系列的手持式設計,在機身機構上帶來了非常大的創新,因此清潔方式也變得與眾不同。近日,鈦媒體編輯也親身體驗了這款產品,作為戴森迄今最靈活、最輕的吸塵器, 戴森Omni-glide到底有哪些獨特的亮點所在?
  • 戴森Omni-glide萬向吸塵器正式發布 售價3390元起
    12月1日上午,戴森Omni-glide萬向吸塵器正式在中國市場亮相。作為戴森新一代主打全新吸塵方式的無繩吸塵器產品,Omni-glide萬向吸塵器配置了戴森首款萬向軟絨滾筒吸頭,採用了全新的直線機身設計配合點按式電源開關。其外觀極簡、機身輕巧,但卻濃縮了戴森的各項先進核心科技,性能更加卓越,適合都市緊湊的生活空間和複雜的家居布局。
  • 【新品】熱銷跑鞋全新升級 adi snova glide 5
    阿迪達斯跑步近期發布了一款熱銷跑鞋全新升級力作snova glide 5,通過搭載阿迪達斯最新科技以及先鋒設計理念
  • 顛覆傳統單向吸塵清潔方式,戴森發布Omni-glide萬向吸塵器
    直線機身解鎖清潔新姿勢戴森Omni-glide的不同首先在於結構上,它首次採用直線機身設計,機身更加輕巧,外觀也更簡約,配合點按式電源開關,讓清潔姿勢不再受限,以多樣化的吸塵體驗,滿足年輕人對顏值、娛樂性和舒適便捷的多重需求。
  • 全面轉變年輕一代清潔方式,戴森Omni-glide萬向吸塵器重磅發布
    今日,戴森Omni-glide萬向吸塵器於上海重磅發布。作為戴森迄今最靈活、最輕的吸塵器,戴森Omni-glide萬向吸塵器顛覆了傳統單向吸塵清潔方式,在使用戴森首款萬向軟絨滾筒吸頭的同時,採用了全新的直線機身設計配合點按式電源開關,全方位地轉變你的清潔方式。
  • 戴森發布Omni-glide萬向吸塵器,搭配首款萬向軟絨滾筒吸頭
    戴森Omni-glide萬向吸塵器於上海重磅發布。作為戴森迄今最靈活[1]、最輕[2]的吸塵器,戴森Omni-glide萬向吸塵器顛覆了傳統單向吸塵清潔方式[3],在使用戴森首款萬向軟絨滾筒吸頭[4]的同時,採用了全新[5]的直線機身設計配合點按式電源開關,全方位地轉變你的清潔方式。
  • 架構設計
    設計模式類這一類圖書則一下子進入架構的局部細節,每個模式的來龍去脈並不容易理解。就算理解了某個具體的模式,但是也很難真正做到活學活用,不知道還是不知道。分布式系統架構設計類這類圖書通常從服務端的通用問題如一致性、高可用、高並發挑戰等話題講起,講大型業務系統面臨的挑戰。
  • 戴森Omni-glide萬向吸塵器重磅發布,簡約帶感開啟嶄新清潔方式
    正因如此,戴森在今天發布了顛覆傳統單向吸塵清潔方式的新品——戴森Omni-glide萬向吸塵器,這款吸塵器針對年輕消費者的真實需求,無論是造型還是功能上都進行了重新設計,與戴森的前幾代無繩吸塵器產品相比有著突破性的區別。它究竟為年輕用戶帶來了哪些改變和便利呢?
  • 一經發布的戴森Omni-glide萬向吸塵器就遭遇了口碑滑鐵盧
    一經發布的戴森Omni-glide萬向吸塵器就遭遇了口碑滑鐵盧 一經發布的戴森Omni-glide萬向吸塵器就遭遇了口碑滑鐵盧 2020-12-02 17:27:43  來源:網際網路
  • 豐富花藝之美|花藝架構設計
    架構不等於花藝架構是用來體現花藝作品的一個載體手法多樣,作品新穎是為花藝服務的時尚前衛的架構花藝作品造型豐富表現力強,可選用材料寬泛被越來越多地應用在各種場合傳統插花的技法主要有修剪、彎曲和固定三類而現代花藝的創作技法比傳統插花有很大發展且豐富很多如鋪陳、重疊、階梯、纏繞、分解、透視、架構、粘貼等為現代花藝造型的創作提供了豐富的創作手段架構花藝,起源於西方