Glide 和 Picasso 可以說是目前 Android 上最流行的圖片加載庫了。大部分安卓應(yīng)用開發(fā)人員都有使用過這兩個庫在他們的開發(fā)工作中。這兩個庫也都確實提供了大量圖片加載的功能,而且也都經(jīng)過了很多應(yīng)用的檢驗,是可靠可信的。表面看上去似乎兩者工作原理很相似,但是實際上是有著很大差別的,主要體現(xiàn)在下面幾個方面:
- 下載圖片的方式
- 圖片的緩存機制
- 加載到內(nèi)存的機制
本文主要會圍繞這幾個方面來深入研究和對比兩個庫的差異,從而給開發(fā)者們提供參考。
對比的版本是 Glide v3.7.0 和 Picasso v2.5.2 的版本。
導(dǎo)入庫到項目中
Picasso 和 Glide 都在 Jcenter 上有建立庫,所以只需要簡單的在添加dependency 即可
Picasso
dependencies {
compile 'com.squareup.picasso:picasso:2.5.1'
}
Glide
dependencies {
compile 'com.github.bumptech.glide:glide:3.5.2'
}
庫的大小和方法的數(shù)量
對比兩個.jar 庫的大小,Glide 要比 Picasso 大很多,基本上是 Picasso 的3.5倍:
從庫的大小,我們就可以預(yù)見,Glide 的方法必然是要大于Picasso 的,Picasso 的方法 總共有849個,而 Glide 的有2678個:
使用方式
如果只是簡單的從一個 URL 中下載圖片,然后顯示到 imageView 中,那么兩個庫的使用方式基本相似,也都非常的簡單。同時兩個庫也都支持動畫和大小的剪切,也可以設(shè)置加載時候的預(yù)設(shè)圖片等功能:
Picasso:
Picasso.with(myFragment)
.load(url)
.centerCrop()
.placeholder(R.drawable.loading_spinner)
.into(myImageView);
Glide:
Glide.with(myFragment)
.load(url)
.centerCrop()
.placeholder(R.drawable.loading_spinner)
.crossFade()
.into(myImageView);
但是,Glide 這里有一個非常招人喜歡的地方,就是 Glide 在設(shè)計的時候,就有 Activity 和 Fragment 的生命周期。什么意思呢? 就是說你可以傳遞 Activity 或者 Fragment 的 context 給 Glide.with(), 然后 Glide 就會非常智能的同 Activity 的生命周期集成, 比如 OnResume 或者 onPause():
緩存大小
兩個庫也都支持緩存圖片,都通過下載圖片后,緩存到本地。但是這里對于緩存本地的機制,兩個庫是完全不同的做法。
Picasso 是下載圖片然后緩存完整的大小到本地,比如說圖片的大小是1080p的,之后如果我需要同一張圖片,就會返回這張 full size 的,如果我需要resize,也是對這種 full size 的做 resize。
Glide 則是完全不一樣的做法。Glide 是會先下載圖片,然后改變圖片的大小,以適應(yīng) imageView 的要求,然后緩存到本地。 所以如果你是下載同一張圖片,但是設(shè)定兩個不一樣大小的 imageView, 那么Glide 實際上是會緩存兩份。
換個角度來看,這里不僅僅是緩存的問題,比如一個 ImageView 要改變它的大小,PIcasso 就只需要下載一次 full size 的圖片,但是 Glide 實際上就不僅僅是下載一次了,它需要去單獨下載然后改變大小適配 imageView,因為對于 Glide 來講,需要緩存不同大小的同一張圖片。
從這點來看,似乎 Glide 的這種設(shè)計很有問題了?當(dāng)然不是,這種做法也會帶來一定的好處,在下面的memory中就會展示。
內(nèi)存使用
Glide 默認(rèn)是用的 RGB_555 的設(shè)定,PIcasso 則是用的 ARGB _8888的設(shè)定。為了公平起見,我這里修改了 GlideModule,讓 Glide 也使用 ARGB _8888的格式,做法也很簡單,新建一個類然后繼承 GlideModule
<meta-data android:name="example.com.myanimation.GlideConfiguration" android:value="GlideModule"/>
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.
}
}
下面是兩者加載的對比:
可以看出 Glide (大約8MB) 要比 Picasso (13 MB) 的少不少。其實這里就體現(xiàn)出了之前提到的 Glide 緩存的方式問題。Picasso 是緩存的 full size 圖片的大小,而 Glide 是加載已經(jīng)改變大小后的圖片,顯而易見使用的memory會小很多。 這樣可以減少 OutOfMemoryError 的可能性。
加載圖片的時間
這里先說明下,當(dāng)嘗試加載一個圖片的時候,兩個庫都會采用先從緩存中讀取,如果緩存中沒有,再去下載的做法。
實際試驗中,Picasso 會比 Glide 快一點。猜測可能的原因還是因為之前講到的緩存機制導(dǎo)致,因為Picasso 是直接把圖加載到內(nèi)存中,而 Glide 則需要改變圖片大小再加載到內(nèi)存中去。這個應(yīng)該是會耗費一定的時間。
但是,當(dāng)加載圖片從內(nèi)存中的時候,Glide 則比 Picasso 要快。其原理還是因為緩存機制的區(qū)別。因為Picasso 從緩存中拿到的圖片,還要先去 resize 后,然后設(shè)定給 imageView,但是 Glide 則不需要這樣。
其他功能的對比
GIF 支持:Glide 支持 GIF。 對于加載 GIF 來說,Glide 只需要簡單使用 Glide.with(...).load(...)。 但是 Picasso 是不支持的,因此如果你的應(yīng)用中是需要加載 GIF 的話,那就只能用 Glide 了。
靈活性:Glide 提供了非常多的配置,你可以非常靈活的根據(jù)你的需求來客制化,從而縮減 Glide 庫的大小等。
結(jié)論
正所謂人無完人,經(jīng)過一番對比,Picasso 和 Glide 各有千秋,那么到底我們應(yīng)該用哪個庫呢?這個還是回到應(yīng)用的需求來看,比如你想要你的 app 小一些,沒有那么多的額外功能,那么 Picasso 是你的首選。反之,比如你的應(yīng)用中需要加載 GIF,或者對于內(nèi)存的大小比較在意,那么 Glide 應(yīng)該是不錯的選擇。
實際上,就我個人來看,Glide 要略優(yōu)于 Picasso. 特別是支持 GIF,這個殺手锏啊!