之前,Google推出了一個圖片加載庫Glide。因爲我們之前使用的ImageLoader偏多了,所以現在我就準備研究一下Glide這個框架。
首先,我要先說的是好,Glide這個庫看起來跟Picasso這個庫非常的相似,感覺glide應該是Picasso庫的翻版。那麼第一章,我們就PK一下glide和Picasso。
導入庫
Picasso
dependencies {
compile 'com.squareup.picasso:picasso:2.5.1'
}
glide
dependencies {
compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.android.support:support-v4:22.0.0'
}
glide需要android support library v4,所以在你的項目中,不要忘記導入support-v4包。
基本使用
說他們倆很像,其實就是在使用上兩者很像。
Picasso
Picasso.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
glide
Glide.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
雖然兩者使用起來看着很像,但是glide設計的更加好,因爲glide.with(context)中,可以支持activity和fragment,context會自動識別轉化的。我們可以看一下源碼:
public static RequestManager with(Context context) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(context);
}
public static RequestManager with(Activity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
可以看到這裏,不僅可以傳context還可以傳activity和fragment對象,這樣我們使用起來就不用轉化context了。當然在在傳入context的函數中,glide還做了識別處理,源碼如下:
public RequestManager get(Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
又把屬於fragment和activity的context又識別了一波。
傳入activity或fragment的好處:圖片加載將會跟着activity和fragment的生命週期活動,activity或fragment生命週期onPause的時候,圖片就會pause加載,onResume的時候,圖片就會onResume加載。所以推薦,不要傳入context到glide,儘量傳activity或者fragment。
默認bitmap格式是 RGB_565
glide默認的bitmap格式是RGB_565,這個比Picasso只用的ARGB_8888少用一半的內存,所以glide圖片展示沒有Picasso清晰,下面是兩個內存消耗比較:
但是如果你需要高質量的圖片,你需要把bitmap格式轉化爲ARGB_8888,你需要實現一個接口GlideModule,如下:
public class GlideConfiguration implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
然後在AndroidManifest定義一個meta-data,如下:
<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
android:value="GlideModule"/>
這樣的話,glide圖片看起來好多了。
變成ARGB_8888後,glide內存消耗也變大了,但是仍然比Picasso小。
這是爲啥咧?
假設我們要加載一個1920x1080的圖片,Picasso會將整個圖片加載下來,而glide加載的是imageview大小(假設我們imageview大小是768x432)
Disk緩存
當我的imageview有不同的size,而且同時加載一張圖片,Picasso硬盤緩存只緩存這一張圖片,但是glide機制不一樣,因爲glide加載的imageview,所以你如果有不同size的imageview,雖然是同一張圖片,但是glide還是會將這些不同size的imageview都緩存下來。
當然你可以通過下面的方法:
Glide.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(ivImgGlide);
這樣的話,緩存全大小的圖片,然後在resize和cache。
glide默認這種加載方式,也有好處,就是加載速度快,Picasso緩存全尺寸圖片,加載到imageview還需要測量imageview的大小進行裁剪,而glide加載的圖片不需要測量大小,所以glide加載速度很快。
glide能做,Picasso不能做的
glide可以load gif圖片,而Picasso做不到。
庫大小
哈哈,glide大小能頂Picasso的四倍了,方法數也多了很多。
總結
glide和Picasso pk結果:
glide優點:加載速度快,可以處理gif、video等圖片流。
Picasso優點:體積小,圖片質量高。