文/吳玄玄 馬旭平
圖片加載已經成為Android開發中最基礎的功能,圖片加載OOM問題也一直困擾很多開發者,android開發者為了降低開發周期、難度以及減少OOM,越來越多開發者傾向于開源圖片加載框架,開源圖片加載框架已經占據了很大比例市場,Glide作為最近幾年新興的開源圖片加載框架對Android圖片加載起了不可忽視的作用。Glide是Google一位員工的作品,Glide完全是基于Picasso開源框架,沿襲了Picasso簡潔的風格,但在此基礎上該員工做了大量的優化與改進。
目前,android市場上的app大多已采用開源圖片加載框架,例如: Fresco、Picasso、Glide等。Fresco是Facebook推出的一款用于Android應用中展示圖片的強大圖片加載框架,它提供了圖片下載、漸進式加載、內存管理等功能,很大程度上把開發者從繁瑣的圖片管理中解放出來,但它只支持自己的控件。Picasso是Square公司出品的一款非常優秀的開源圖片加載框架,是目前Android開發中很受歡迎的圖片加載框架之一。Glide作為Google在泰國舉行的谷歌開發者論壇上推出的開源圖片加載框架,已被大多數開發者所接受。作為幾種主流的開源圖片加載框架,Glide、Picasso、Fresco對圖片的處理各有千秋,本文主要通過對比分析Glide與其它兩種開源圖片加載框架差異。

圖1:Fresco、Picasso、Glide庫大小
本部分主要從引入庫大小、加載圖片占用內存大小、易用性三個方面對比分析Glide、Picasso、Fresco。
Glide、Picasso、Fresco作為主流開源圖片加載框架對圖片的加載支持是比較完美的,在使用Glide、Picasso、Fresco三者的庫時,只需在dependencies中添加一行代碼即可,但三者引入庫的大小卻大不相同,Fresco 0.12.0 版本庫大小為16.78Mb,Picasso 2.71828版本庫大小為106.4Kb ,Glide 4.9.0版本的庫大小為403.01Kb。通過庫大小的對比(如圖1所示),發現Fresco庫太過于龐大,若是應用要求簡潔輕量,Fresco將不做考慮。
除此之外,Picasso的整個庫可分為Dispatcher、Requesthandlery以 及Downloader、PicassoDrawable等 模 塊。Picasso在收到加載以及顯示圖片的任務時,創建Request并將它交給Dispatcher,Dispatcher分發任務到具體RequestHandler,任務通過MemoryCache顯示到Target中。
Glide整個庫分為RequestManager(請求管理器)、Engine(數據獲取引擎)、Fetcher(數據獲取器)、MemoryCache(內存緩存)、Registry(圖片類型及解析器配置)、Target(目標)等模塊。當Glide收到加載及顯示圖片的任務時,創建Requset并將它交給RequesManager,Request啟動Engine通過Fetcher獲取數據資源,Transformation處理后交給Target。
Picasso庫模塊少于Glide,圖片處理流程調用庫模塊較少,加載圖片速度較快,若對圖片加載速度有要求,Picasso會是首選。
Fresco加載圖片時把圖片放到一個特別的內存區(Ashmem區),當圖片不顯示的時候,占用的內存會自動釋放,從而減少內存空間的占用,這會使應用更加流暢,減少因圖片占用內存引發的OOM,但Fresco的圖片加載用法太復雜,不適用于輕量型應用,故應用若是對大小有要求,不宜使用Fresco。Picasso加載圖片采用的是ARGB-8888格式,Glide加載圖片默認采用Bitmap格式RGB-565,由于加載格式的不同,導致Glide加載圖片的質量不如Picasso,但Glide所占內存較小,即使是把Glide加載圖片的格式調整為ARGB-8888,Glide、所占的內存仍遠遠小于Picasso。Picasso加載圖片是加載全尺寸的圖片到內存,然后讓GPU實時重繪大小,而Glide加載圖片的大小是和ImageView的大小一致的。
在加載圖片這方面,Glide是優于Picasso的,Glide加載圖片占用內存小,除此之外,Glide可以自動計算出任意情況下ImageView的大小,圖片加載速度會更快,在上述這些方面Glide優于Picasso與Fresco。
在圖片加載的易用性上,Glide與Picasso也是完勝Fressco的,大多數情況下Glide與Picasso圖片加載只需一行代碼即可,Fresco使用方法較復雜,代碼量較多,在易用性方面較差。Glide與 Picasso非常相似,圖片加載方式如出一轍,Glide的with()方法不止可以接受Content,還可以接受Fragment和Activity,最重要的是將Activity與Fragment作為with()參數圖片加載會和Activity與Fragment的生命周期保持一致,有利于對資源進行管理。
本部分從引入庫大小、加載圖片占用內存大小、易用性等方面來分析不難發現Glide優于Picasso與Fresco。
Fresco、Picasso、 Glide作為主流開源圖片加載框架,三者的緩存機制也是不同的。
Fresco采用的是三級緩存:
(1)Bitmap緩存:Bitmap對象可以立刻用來顯示或者用于后處理;
(2)未解碼圖片的內存緩存:原始壓縮格式的圖片,從該緩存取到的圖片在使用之前,需要先進行解碼;
(3)文件緩存:文件緩存存儲的是未解碼的原始壓縮格式的圖片,在使用之前同樣需要經過解碼等處理。
Picasso自帶兩級緩存:內存緩存以及硬盤緩存。Picasso無本地緩存,它把此功能交給了Square 的另外一個網絡庫 okhttp 去實現,這樣做的好處在于可以通過請求Response Header中的 Cache-Control及Expired控制圖片的過期時間。
Glide加載圖片使用的是四級緩存:
(1)資源緩存;
(2)內存緩存;
(3)磁盤緩存;
(4)文件緩存。
Glide在開始一個新的圖片請求之前會檢查多級緩存,首先,判斷當前是否有正在展示的這張圖片資源,若是有,則直接返回圖片資源,無則到內存中檢查是否存在;內存中若是存在則返回圖片資源,無則判斷圖片是否寫入過磁盤緩存;磁盤中若是存在則返回圖片,無則檢查是否寫入過文件緩存;文件緩存若是存在則返回圖片,無則直接到原始資源取回數據。
Glide的四級緩存使得其圖片加載速度相比于Picasso與Fresco會快一些,另外四級緩存還可以減少對數據源的訪問量,減輕服務器的壓力。從緩存機制方面來分析,Glide會是圖片加載框架更好的選擇。
Android應用開發大多數是加載靜態圖片,而有的則需要加載動態圖片即GIF。Glide、Fresco作為主流開源圖片加載框架對GIF加載是完美支持的,而Picasso不支持顯示GIF,在此技術方面Picasso將會被排除。若是應用無需加載GIF,則Picasso會是首選,因為Picasso包較小,相應的應用體積也會較小,并且圖片加載質量也不差;反之若是需加載GIF,由于Fresco包較大,并且使用較復雜,Glide當為首選。除此之外,Glide內部會自動識別圖片類型,不管我們傳入的是一張普通圖片還是一張GIF,Glide都會自動判別從而正確地把它解析并展示出來。加載GIF是Glide非常特色的一個功能,并且這個功能我們并不需要編寫額外代碼,在加載GIF方面來分析,GIF的加載Glide當為不二選擇。
Glide除了支持加載GIF以外,還可以加載本地視頻,這是其它開源圖片加載框架所不具備的。Glide視頻加載與圖片加載類似,只需獲得本地視頻地址,并把load()參數設置為load(Uri.fromFile(newFile(filePath)))即 可,其中filePath是需加載的視頻文件地址。Picasso與Fresco對此不支持,這是Glide的一大特色,若是應用需加載本地視頻則優先考慮使用Glide。
Glide、Picasso、Fresco使用場景對比如圖2所示。
Fresco雖然功能強大,但是包也很大,依賴很多,使用復雜,而且還要在布局使用SimpleDraweeView控件加載圖片。除此之外,Fresco獲取bitmap比較復雜,使用起來并不是那么方便,但它可以大大減少OOM,適用于需要高性能加載大量圖片的場景,若是應用對體積無要求可以使用Fresco。另外,若是專業的圖片應用,對圖片質量等要求較高,Fresco也當為首選。

圖2:使用場景分析
Picasso與Glide,Picasso所能做到的Glide也能做到,只是所需配置不同,但Picasso包體積比Glide小,而且圖片質量高,若是無GIF加載、對圖片質量要求較高且應用體積較小,則可以選擇Picasso。
Glide作為Picasso的升級版,除了具有Picasso優點之外,還支持加載GIF,圖片加載速度較快,若是需要處理大型的圖片流,或者制作視頻類應用,或者對圖片的質量不是很注重,Glide當為首選。
除此之外,Glide對新手比較友好,上手快,使用簡單,配置方便,對一般應用而言是不錯的選擇。
本文主要從圖片加載、圖片緩存、GIF加載、本地視頻加載、使用場景等方面,通過Glide與Fresco、Picasso主流開源圖片加載框架對比,對Glide開源圖片加載框架進行分析,并通過分析說明Glide特點以及使用場景,供廣大開源圖片加載框架使用者參考。