Glide & Picasso
因為Glide和Picasso的api差不多,所以比較起來更容易一點,就先比較這兩個好了。
依賴
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。其實Support Library v4已經是應用程序的標配了,這不是什么問題。
使用
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);
盡管它們看起來差不多,但是設計上Glide做得更好:因為Glide的with方法不光接受Context,還接受Activity 和 Fragment,Context會自動的從他們獲取。
將Activity/Fragment傳給Glide的好處是:圖片加載會和Activity/Fragment的生命周期保持一致,比如Paused狀態在暫停加載,在Resumed的時候又自動重新加載。所以我建議傳參的時候傳遞Activity 和 Fragment給Glide,而不是Context。
默認加載格式 & 內存消耗
下面是將1920x1080的圖片加載進入768x432大小的ImageView的對比圖

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

當然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.
}
}
同時在AndroidManifest.xml中將GlideModule定義為meta-data
<meta-data android:name="com.name.GlideConfiguration"
android:value="GlideModule"/>
在指定了Glide的加載格式之后,我們再來看看內存消耗的對比圖

可以看到,Picasso占用的內存依然比Glide大。這是因為Picasso加載的是完整的圖像(1920x1080)進入內存的。
而Glide是加載的真實ImageView(768x432)的大小進入內存的。
當然Picasso是可以調整加載圖像的大小:
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.resize(768, 432)
.into(ivImgPicasso);
當然,有時候你還無法明確的知道ImageView的大小,所以你還可以這么做:
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.fit()
.centerCrop()
.into(ivImgPicasso);

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