1、比較 Picasso 與 Glide
總體來(lái)說(shuō)二者極為相似,有著近乎相同的 API 的使用風(fēng)格,但 Glide 在緩存策略和加載 gif 方面略勝一籌。
基礎(chǔ)
Glide 和 Picasso 非常相似,Glide 加載圖片的方式和 Picasso 如出一轍。
雖然兩者看起來(lái)一樣,但 Glide 更易用,因?yàn)?Glide 的 with 方法不光接受 Context,還接受 Activity 和 Fragment,Context 會(huì)自動(dòng)的從他們獲取,同時(shí)將 Activity/Fragment 作為 with()參數(shù)的好處是:圖片加載會(huì)和 Activity/Fragment 的生命周期保持一致,比如 Paused 狀態(tài)在暫停加載,在 Resumed 的時(shí)候又自動(dòng)重新加載。
圖像和內(nèi)存
同樣將 1920×1080 像素的圖片加載到 768×432 的 ImageView 中,Glide 加載的圖片質(zhì)量要差于Picasso,這是因?yàn)?Glide 默認(rèn)的 Bitmap 格式是 RGB-565 ,比 ARGB-8888 格式的內(nèi)存開(kāi)銷要小一半。想要提高 Glide 的圖片效果,可以創(chuàng)建一個(gè)新的 GlideModule 將 Bitmap 格式轉(zhuǎn)換到 ARGB-8888。同時(shí)在 AndroidManifest.xml 中將 GlideModule 定義為 meta-data。
修改了 Bitmap 格式后,Glide 將花費(fèi)兩倍于上次的內(nèi)存,但是仍遠(yuǎn)遠(yuǎn)小于 Picasso 的內(nèi)存開(kāi)銷,原因在于 Picasso 是加載了全尺寸的圖片到內(nèi)存,然后讓 GPU 來(lái)實(shí)時(shí)重繪大小。而 Glide 加載的大小和 ImageView 的大小是一致的,當(dāng)然,Picasso 也是可以指定加載圖片大小的,但是問(wèn)題在于你需要主動(dòng)計(jì)算 ImageView 的大小,或者說(shuō)你的 ImageView 大小是具體的值(而不是 wrap_content )
在加載圖片這個(gè)問(wèn)題上 Glide 完勝 Picasso,因?yàn)?Glide 可以自動(dòng)計(jì)算出任意情況下的 ImageView 大小。
Image質(zhì)量的細(xì)節(jié)
將 ImageView 還原到真實(shí)大小時(shí),Glide 加載的圖片沒(méi)有 Picasso 那么平滑。
磁盤緩存
Picasso 和 Glide 在磁盤緩存策略上有很大的不同。Picasso 緩存的是全尺寸的,而 Glide 緩存的是跟 ImageView 尺寸相同的。我們可以將 ImageView 調(diào)整成不同大小,但不管大小如何 Picasso 只緩存一個(gè)全尺寸的。Glide 則不同,它會(huì)為每種大小的 ImageView 緩存 一次。盡管一張圖片已經(jīng)緩存了一次,但是假如你要在另外一個(gè)地方再次以不同尺寸顯示,需要重新下載,調(diào)整成新尺寸的大小,然后將這個(gè)尺寸的也緩存起來(lái)。具體說(shuō)來(lái)就是:假如在第一個(gè)頁(yè)面有一個(gè) 200×200 的 ImageView,在第二個(gè)頁(yè)面有一個(gè) 100×100 的 ImageView,這兩個(gè) ImageView 本來(lái)是要顯示同一張圖片,卻需要下載兩次。不過(guò),你可以通過(guò)代碼改變這種行為,讓Glide既緩存全尺寸又緩存其他尺寸,
這樣就使得下次在任何 ImageView 中加載圖片的時(shí)候,全尺寸的圖片將從緩存中取出,重新調(diào)整大小,然后緩存。
Glide 的這種方式優(yōu)點(diǎn)是加載顯示非??臁6?Picasso 的方式則因?yàn)樾枰陲@示之前重新調(diào)整大小而導(dǎo)致一些延遲。不過(guò) Glide 比 Picasso 需要更大的空間來(lái)緩存。
特性
Glide 可以做到和 Picasso 幾乎一樣多的事,代碼也幾乎一樣。但 Glide 可以加載 GIF 動(dòng)態(tài)圖,而 Picasso 不能,但是 Glide 動(dòng)畫(huà)會(huì)消費(fèi)太多的內(nèi)存,因此謹(jǐn)慎使用。除了 gif 動(dòng)畫(huà)之外,Glide 還可以將任何的本地視頻解碼成一張靜態(tài)圖片。還有一個(gè)特性是你可以配置圖片顯示的動(dòng)畫(huà),而 Picasso 只有一種動(dòng)畫(huà):fading in,最后一個(gè)是可以使用 thumbnail()產(chǎn)生一個(gè)你所加載圖片的 thumbnail。其實(shí)還有一些特性,不過(guò)不是非常重要,比如將圖像轉(zhuǎn)換成字節(jié)數(shù)組等。
2、Fresco
內(nèi)存管理
Fresco 的最大亮點(diǎn)在于它的內(nèi)存管理。解壓后的圖片,即 Android 中的 Bitmap ,占用大量的內(nèi)存,在 Android 5.0以下系統(tǒng)中,這會(huì)顯著地引發(fā)界面卡頓。而使用 Fresco 將很好地解決這個(gè)問(wèn)題,F(xiàn)resco 會(huì)將圖片放到一個(gè)特別的內(nèi)存區(qū)域,當(dāng)圖片不再顯示的時(shí)候,占用的內(nèi)存會(huì)自動(dòng)被釋放,這會(huì)使得 APP 更流暢,減少因圖片內(nèi)存占用而引發(fā)的 OOM。當(dāng) APP 包含的圖片較多時(shí),這個(gè)效果尤其明顯。
圖像
Fresco 支持圖像的漸進(jìn)式呈現(xiàn),漸進(jìn)式的圖片格式先呈現(xiàn)大致的圖片輪廓,然后隨著圖片下載的繼續(xù),逐漸呈現(xiàn)清晰的圖片,這在低網(wǎng)速情況下瀏覽圖片十分有幫助,可以帶來(lái)更好地用戶體驗(yàn)。另外,F(xiàn)resco 支持加載 gif 圖,支持 WebP 格式。
3、總結(jié)
ImageLoader 優(yōu)點(diǎn)
(1) 支持下載進(jìn)度監(jiān)聽(tīng)
(2) 可以在 View 滾動(dòng)中暫停圖片加載
通過(guò) PauseOnScrollListener 接口可以在 View 滾動(dòng)中暫停圖片加載。
(3) 默認(rèn)實(shí)現(xiàn)多種內(nèi)存緩存算法
這幾個(gè)圖片緩存都可以配置緩存算法,不過(guò) ImageLoader 默認(rèn)實(shí)現(xiàn)了較多緩存算法,如 Size 最大先刪除、使用最少先刪除、最近最少使用、先進(jìn)先刪除、時(shí)間最長(zhǎng)先刪除等。
(4) 支持本地緩存文件名規(guī)則定義
Picasso 優(yōu)點(diǎn)
(1) 自帶統(tǒng)計(jì)監(jiān)控功能
支持圖片緩存使用的監(jiān)控,包括緩存命中率、已使用內(nèi)存大小、節(jié)省的流量等。
(2) 支持優(yōu)先級(jí)處理
每次任務(wù)調(diào)度前會(huì)選擇優(yōu)先級(jí)高的任務(wù),比如 App 頁(yè)面中 Banner 的優(yōu)先級(jí)高于 Icon 時(shí)就很適用。
(3) 支持延遲到圖片尺寸計(jì)算完成加載
(4) 支持飛行模式、并發(fā)線程數(shù)根據(jù)網(wǎng)絡(luò)類型而變
手機(jī)切換到飛行模式或網(wǎng)絡(luò)類型變換時(shí)會(huì)自動(dòng)調(diào)整線程池最大并發(fā)數(shù),比如 wifi 最大并發(fā)為 4, 4g 為 3,3g 為 2。
這里 Picasso 根據(jù)網(wǎng)絡(luò)類型來(lái)決定最大并發(fā)數(shù),而不是 CPU 核數(shù)。
(5) “無(wú)”本地緩存
無(wú)”本地緩存,不是說(shuō)沒(méi)有本地緩存,而是 Picasso 自己沒(méi)有實(shí)現(xiàn),交給了 Square 的另外一個(gè)網(wǎng)絡(luò)庫(kù) okhttp 去實(shí)現(xiàn),這樣的好處是可以通過(guò)請(qǐng)求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過(guò)期時(shí)間。
Glide 優(yōu)點(diǎn)
(1) 圖片緩存->媒體緩存
Glide 不僅是一個(gè)圖片緩存,它支持 Gif、WebP、縮略圖。甚至是 Video,所以更該當(dāng)做一個(gè)媒體緩存。
(2) 支持優(yōu)先級(jí)處理
####### (3) 與 Activity/Fragment 生命周期一致,支持 trimMemory
Glide 對(duì)每個(gè) context 都保持一個(gè) RequestManager,通過(guò) FragmentTransaction 保持與 Activity/Fragment 生命周期一致,并且有對(duì)應(yīng)的 trimMemory 接口實(shí)現(xiàn)可供調(diào)用。
(4) 支持 okhttp、Volley
Glide 默認(rèn)通過(guò) UrlConnection 獲取數(shù)據(jù),可以配合 okhttp 或是 Volley 使用。實(shí)際 ImageLoader、Picasso 也都支持 okhttp、Volley。
(5) 內(nèi)存友好
① Glide 的內(nèi)存緩存有個(gè) active 的設(shè)計(jì)
從內(nèi)存緩存中取數(shù)據(jù)時(shí),不像一般的實(shí)現(xiàn)用 get,而是用 remove,再將這個(gè)緩存數(shù)據(jù)放到一個(gè) value 為軟引用的 activeResources map 中,并計(jì)數(shù)引用數(shù),在圖片加載完成后進(jìn)行判斷,如果引用計(jì)數(shù)為空則回收掉。
② 內(nèi)存緩存更小圖片
Glide 以 url、view_width、view_height、屏幕的分辨率等做為聯(lián)合 key,將處理后的圖片緩存在內(nèi)存緩存中,而不是原始圖片以節(jié)省大小
③ 與 Activity/Fragment 生命周期一致,支持 trimMemory
④ 圖片默認(rèn)使用默認(rèn) RGB_565 而不是 ARGB_888
雖然清晰度差些,但圖片更小,也可配置到 ARGB_888。
其他:Glide 可以通過(guò) signature 或不使用本地緩存支持 url 過(guò)期