Glide & Picasso
因?yàn)镚lide和Picasso的api差不多,所以比較起來(lái)更容易一點(diǎn),就先比較這兩個(gè)好了。
依賴
Glide
dependencies {
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:19.1.0'
}
Picasso
dependencies {
compile 'com.squareup.picasso:picasso:2.5.2'
}
別忘了Glide需要依賴Support Library v4。其實(shí)Support Library v4已經(jīng)是應(yīng)用程序的標(biāo)配了,這不是什么問題。
使用
Glide
Glide.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
Picasso
Picasso.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
盡管它們看起來(lái)差不多,但是設(shè)計(jì)上Glide做得更好:因?yàn)镚lide的with方法不光接受Context,還接受Activity 和 Fragment,Context會(huì)自動(dòng)的從他們獲取。

將Activity/Fragment傳給Glide的好處是:圖片加載會(huì)和Activity/Fragment的生命周期保持一致,比如Paused狀態(tài)在暫停加載,在Resumed的時(shí)候又自動(dòng)重新加載。所以我建議傳參的時(shí)候傳遞Activity 和 Fragment給Glide,而不是Context。
默認(rèn)加載格式 & 內(nèi)存消耗
下面是將1920x1080的圖片加載進(jìn)入768x432大小的ImageView的對(duì)比圖

Glide默認(rèn)的Bitmap格式是RGB_565,比ARGB_8888的內(nèi)存開銷要少50%。
下圖是Picasso和Glide的內(nèi)存消耗比較圖(基礎(chǔ)的application就消耗了大概8MB)

當(dāng)然Glide也是可以指定加載格式的:
public class GlideConfiguration implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
}
}
同時(shí)在AndroidManifest.xml中將GlideModule定義為meta-data
<meta-data android:name="com.name.GlideConfiguration"
android:value="GlideModule"/>
在指定了Glide的加載格式之后,我們?cè)賮?lái)看看內(nèi)存消耗的對(duì)比圖

可以看到,Picasso占用的內(nèi)存依然比Glide大。這是因?yàn)镻icasso加載的是完整的圖像(1920x1080)進(jìn)入內(nèi)存的。
而Glide是加載的真實(shí)ImageView(768x432)的大小進(jìn)入內(nèi)存的。
當(dāng)然Picasso是可以調(diào)整加載圖像的大小:
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.resize(768, 432)
.into(ivImgPicasso);
當(dāng)然,有時(shí)候你還無(wú)法明確的知道ImageView的大小,所以你還可以這么做:
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.fit()
.centerCrop()
.into(ivImgPicasso);

緩存
Picasso和Glide在磁盤緩存策略上有很大的不同;Picasso緩存的是全尺寸的,而Glide緩存的是跟ImageView尺寸相同的。Glide的這種方式優(yōu)點(diǎn)是在同樣大小的ImageView下加載顯示非???。而Picasso的方式則因?yàn)樾枰陲@示之前重新調(diào)整大小而導(dǎo)致一些延遲。
Picasso只緩存一個(gè)全尺寸的。Glide則不同,它會(huì)為每種大小的ImageView緩存 一次。盡管一張圖片已經(jīng)緩存了一次,但是假如你要在另外一個(gè)地方再次以不同尺寸顯示,需要重新下載,調(diào)整成新尺寸的大小,然后將這個(gè)尺寸的也緩存起來(lái)。
當(dāng)然我們也可以讓Glide緩存完整的尺寸:
Glide.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(ivImgGlide);
下次在任何ImageView中加載圖片的時(shí)候,全尺寸的圖片將從緩存中取出,重新調(diào)整大小,然后緩存。
Glide比Picasso多的功能
Glide可以加載GIF動(dòng)態(tài)圖,而Picasso不能。
還有一個(gè)特性是你可以配置圖片顯示的動(dòng)畫,而Picasso只有一種動(dòng)畫:fading in。
包大小
Picasso (v2.5.1)的大小約118kb,而Glide (v3.5.2)的大小約430kb。
Picasso和Glide的方法個(gè)數(shù)分別是840和2678個(gè)。
Fresco
關(guān)于Fresco
Fresco 中設(shè)計(jì)有一個(gè)叫做 Image Pipeline 的模塊。它負(fù)責(zé)從網(wǎng)絡(luò),從本地文件系統(tǒng),本地資源加載圖片。為了最大限度節(jié)省空間和CPU時(shí)間,它含有3級(jí)緩存設(shè)計(jì)(2級(jí)內(nèi)存,1級(jí)磁盤)。
Fresco 中設(shè)計(jì)有一個(gè)叫做 Drawees 模塊,它會(huì)在圖片加載完成前顯示占位圖,加載成功后自動(dòng)替換為目標(biāo)圖片。當(dāng)圖片不再顯示在屏幕上時(shí),它會(huì)及時(shí)地釋放內(nèi)存和空間占用。
特性
內(nèi)存管理
解壓后的圖片,即Android中的Bitmap,占用大量的內(nèi)存。大的內(nèi)存占用勢(shì)必引發(fā)更加頻繁的GC。在5.0以下,GC將會(huì)顯著地引發(fā)界面卡頓。在5.0以下系統(tǒng),F(xiàn)resco將圖片放到一個(gè)特別的內(nèi)存區(qū)域。當(dāng)然,在圖片不顯示的時(shí)候,占用的內(nèi)存會(huì)自動(dòng)被釋放。這會(huì)使得APP更加流暢,減少因圖片內(nèi)存占用而引發(fā)的OOM。Fresco 在低端機(jī)器上表現(xiàn)一樣出色,你再也不用因圖片內(nèi)存占用而思前想后。
圖片加載
Fresco的Image Pipeline允許你用很多種方式來(lái)自定義圖片加載過(guò)程,比如:
- 為同一個(gè)圖片指定不同的遠(yuǎn)程路徑,或者使用已經(jīng)存在本地緩存中的圖片
- 先顯示一個(gè)低清晰度的圖片,等高清圖下載完之后再顯示高清圖
- 加載完成回調(diào)通知
- 對(duì)于本地圖,如有EXIF縮略圖,在大圖加載完成之前,可先顯示縮略圖
- 縮放或者旋轉(zhuǎn)圖片
- 對(duì)已下載的圖片再次處理
- 支持WebP解碼,即使在早先對(duì)WebP支持不完善的Android系統(tǒng)上也能正常使用!
圖片繪制
Fresco 的 Drawees 設(shè)計(jì),帶來(lái)一些有用的特性:
- 自定義居中焦點(diǎn)
- 圓角圖,當(dāng)然圓圈也行
- 下載失敗之后,點(diǎn)擊重現(xiàn)下載
- 自定義占位圖,自定義overlay, 或者進(jìn)度條
- 指定用戶按壓時(shí)的overlay
漸進(jìn)式呈現(xiàn)
漸進(jìn)式的JPEG圖片格式已經(jīng)流行數(shù)年了,漸進(jìn)式圖片格式先呈現(xiàn)大致的圖片輪廓,然后隨著圖片下載的繼續(xù),呈現(xiàn)逐漸清晰的圖片,這對(duì)于移動(dòng)設(shè)備,尤其是慢網(wǎng)絡(luò)有極大的利好,可帶來(lái)更好的用戶體驗(yàn)。
動(dòng)圖加載
加載Gif圖和WebP動(dòng)圖在任何一個(gè)Android開發(fā)者眼里看來(lái)都是一件非常頭疼的事情。每一幀都是一張很大的Bitmap,每一個(gè)動(dòng)畫都有很多幀。Fresco讓你沒有這些煩惱,它處理好每一幀并管理好你的內(nèi)存。
比較
以上說(shuō)的都是一些Fresco的特性或者說(shuō)強(qiáng)大的地方吧。但是它也有一些不是那么完美的地方:
包大小
Fresco > Glide > Picasso
操作
使用 DraweeView 時(shí),請(qǐng)不要使用任何 ImageView 的屬性: 在后續(xù)的版本中,DraweeView 會(huì)直接從 View 派生。任何屬于 ImageView 但是不屬于 View 的方法都會(huì)被移除。
Drawee永遠(yuǎn)會(huì)在getIntrinsicHeight/getIntrinsicWidth中返回-1。所以不能在xml中直接設(shè)置寬高為wrap_content
Fresco獲取Bitmap的操作比較麻煩
相關(guān)鏈接
Introduction to Glide, Image Loader Library for Android, recommended by Google