Glide圖片加載

在build.gradle中添加依賴:

  compile 'com.github.bumptech.glide:glide:3.7.0'

需要support-v4庫的支持,如果你的項目沒有support-v4庫(項目默認已經添加了),還需要添加support-v4依賴:

 compile 'com.android.support:support-v4:23.3.0'

混淆規則:其中第一個混淆規則表明不混淆所有的GlideModule。

-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

簡單使用:

Glide
.with(this)
.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
.into(imageView);

.load()使用

Glide基本可以load任何可以拿到的媒體資源,如:

SD卡資源

load("file://"+ Environment.getExternalStorageDirectory().getPath()+"/test.jpg")

assets資源

load("file:///android_asset/f003.gif")

raw資源

load("android.resource://com.frank.glide/raw/raw_1")或
load("android.resource://com.frank.glide/raw/"+R.raw.raw_1)

drawable資源

load("android.resource://com.frank.glide/drawable/news")或
load("android.resource://com.frank.glide/drawable/"+R.drawable.news)

ContentProvider資源

load("content://media/external/images/media/139469")

http資源

load("[http://img.my.csdn.net/uploads/201508/05/1438760757_3588.jpg](http://img.my.csdn.net/uploads/201508/05/1438760757_3588.jpg)")

簡單設置

1、thumbnail(float sizeMultiplier). 請求給定係數的縮略圖。如果縮略圖比全尺寸圖先加載完,就顯示縮略 圖,否則就不顯示。係數sizeMultiplier必須在(0,1)之間,可以遞歸調用該方法。

2、sizeMultiplier(float sizeMultiplier). 在加載資源之前給Target大小設置係數。

3、diskCacheStrategy(DiskCacheStrategy strategy).設置緩存策略。DiskCacheStrategy.SOURCE:緩存原始數據,DiskCacheStrategy.RESULT:緩存變換(如縮放、裁剪等)後的資源數據,DiskCacheStrategy.NONE:什麼都不緩存,DiskCacheStrategy.ALL:緩存SOURC和RESULT。默認採用DiskCacheStrategy.RESULT策略,對於download only操作要使用DiskCacheStrategy.SOURCE。
priority(Priority priority). 指定加載的優先級,優先級越高越優先加載,但不保證所有圖片都按序加載。枚舉Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL,Priority.LOW。默認爲Priority.NORMAL。

4、dontAnimate(). 移除所有的動畫。
5、animate(int animationId). 在異步加載資源完成時會執行該動畫。
6、animate(ViewPropertyAnimation.Animator animator). 在異步加載資源完成時會執行該動畫。

7、placeholder(int resourceId). 設置資源加載過程中的佔位Drawable。
8、placeholder(Drawable drawable). 設置資源加載過程中的佔位Drawable。

9、fallback(int resourceId). 設置model爲空時要顯示的Drawable。如果沒設置fallback,model爲空時將顯示error的Drawable,如果error的Drawable也沒設置,就顯示placeholder的Drawable。
10、fallback(Drawable drawable).設置model爲空時顯示的Drawable。
11、error(int resourceId).設置load失敗時顯示的Drawable。
12、error(Drawable drawable).設置load失敗時顯示的Drawable。

13、skipMemoryCache(boolean skip). 設置是否跳過內存緩存,但不保證一定不被緩存(比如請求已經在加載資源且沒設置跳過內存緩存,這個資源就會被緩存在內存中)。

14、override(int width, int height). 重新設置Target的寬高值(單位爲pixel)。

15、into(Y target).設置資源將被加載到的Target。
16、into(ImageView view). 設置資源將被加載到的ImageView。取消該ImageView之前所有的加載並釋放資源。
17、into(int width, int height). 後臺線程加載時要加載資源的寬高值(單位爲pixel)。

18、preload(int width, int height). 預加載resource到緩存中(單位爲pixel)。

19、asBitmap(). 無論資源是不是gif動畫,都作爲Bitmap對待。如果是gif動畫會停在第一幀。
20、asGif().把資源作爲GifDrawable對待。如果資源不是gif動畫將會失敗,會回調.error()。

技巧

1.禁止內存緩存

.skipMemoryCache(true)

2.清除內存緩存

 // 必須在UI線程中調用
Glide.get(context).clearMemory();

3.禁止磁盤緩存

.diskCacheStrategy(DiskCacheStrategy.NONE)

4.清除磁盤緩存

 // 必須在後臺線程中調用,建議同時clearMemory()
 Glide.get(applicationContext).clearDiskCache();

5.指定資源的優先加載順序

//優先加載
Glide
    .with(context)
    .load(heroImageUrl)
    .priority(Priority.HIGH)
    .into(imageViewHero);
//後加載
Glide
    .with(context)
    .load(itemImageUrl)
    .priority(Priority.LOW)
    .into(imageViewItem);

6.先顯示縮略圖,再顯示原圖:

  //用原圖的1/10作爲縮略圖
Glide
    .with(this)
    .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
    .thumbnail(0.1f)
    .into(iv_0);
//用其它圖片作爲縮略圖
DrawableRequestBuilder<Integer> thumbnailRequest = Glide
    .with(this)
    .load(R.drawable.news);
Glide.with(this)
    .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
    .thumbnail(thumbnailRequest)
    .into(iv_0);

7.對圖片進行裁剪、模糊、濾鏡等處理:推薦使用獨立的圖片處理庫:wasabeef/glide-transformations,使用也很簡單

  compile 'jp.wasabeef:glide-transformations:2.0.0'

之後我們就可以使用GenericRequestBuilder或其子類的transform()或bitmapTransform()方法設置圖片轉換了:

  //圓形裁剪
Glide.with(this)
    .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
    .bitmapTransform(new CropCircleTransformation(this))
    .into(iv_0);
//圓角處理
Glide.with(this)
    .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
    .bitmapTransform(new RoundedCornersTransformation(this,30,0, RoundedCornersTransformation.CornerType.ALL))
    .into(iv_0);
//灰度處理
Glide.with(this)
    .load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
    .bitmapTransform(new GrayscaleTransformation(this))
    .into(iv_0);
//其它變換...

Glide的“坑”

1、ImageView的setTag問題
問題描述:如果使用Glide的into(imageView)爲ImageView設置圖片的同時使用ImageView的setTag(final Object tag)方法,將會導致java.lang.IllegalArgumentException: You must not call setTag() on a view Glide is targeting異常。因爲Glide的ViewTarget中通過view.setTag(tag)view.getTag()標記請求的,由於Android 4.0之前Tag存儲在靜態map裏,如果Glide使用setTag(int key, final Object tag)方法標記請求則可能會導致內存泄露,所以Glide默認使用view.setTag(tag)標記請求,你就不能重複調用了。
解決辦法:如果你需要爲ImageView設置Tag,必須使用setTag(int key, final Object tag)getTag(int key)方法,其中key必須是合法的資源ID以確保key的唯一性,典型做法就是在資源文件中聲明type="id"的item資源。

2、placeholder()導致的圖片變形問題
問題描述:使用.placeholder()方法在某些情況下會導致圖片顯示的時候出現圖片變形的情況。這是因爲Glide默認開啓的crossFade動畫導致的TransitionDrawable繪製異常,詳細描述和討論可以看一下這個#363issue。根本原因就是你的placeholder圖片和你要加載顯示的圖片寬高比不一樣,而Android的TransitionDrawable無法很好地處理不同寬高比的過渡問題,這的確是個Bug,是Android的也是Glide的。
解決辦法:使用.dontAnimate()方法禁用過渡動畫,或者使用animate()方法自己寫動畫,再或者自己修復TransitionDrawable的問題。

3、ImageView的資源回收問題
問題描述:默認情況下,Glide會根據with()使用的Activity或Fragment的生命週期自動調整資源請求以及資源回收。但是如果有很佔內存的Fragment或Activity不銷燬而僅僅是隱藏視圖,那麼這些圖片資源就沒辦法及時回收,即使是GC的時候。
解決辦法:可以考慮使用WeakReference,如:

 final WeakReference<ImageView> imageViewWeakReference = new WeakReference<>(imageView);
ImageView target = imageViewWeakReference.get();
if (target != null) {
    Glide.with(context).load(uri).into(target);
}

4、ImageView的scaleType問題
scaleType默認爲fitCenter模式,如果你想設置成centerInside,不好意思,3.x還沒有這個方法,參見這個#591issue,折中的解決辦法就是放棄使用centerInside,或者結合android:scaleType="centerInside".dontTransform()使用以禁止Glide對資源進行轉換。如果你想要ImageView的寬高根據圖片資源的大小而定(即使用wrap_comtent),那麼你就必須明確告訴Glide我想加載原始資源:使用android:scaleType="center",或者.dontTransform(),或者
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)

5、異步線程完成後加載圖片的崩潰問題
問題描述:通常情況下,異步線程會被約束在Activity生命週期內,所以異步線程完成後使用Glide加載圖片是沒有問題的。但如果你的異步線程在Activity銷燬時沒有取消掉,那麼異步線程完成後就Glide就無法爲一個已銷燬的Activity加載圖片資源,拋出的異常如下(在with()方法中就進行判斷並拋出異常):

  java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:134)
at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:102)
at com.bumptech.glide.Glide.with(Glide.java:653)
at com.frank.glidedemo.TestActivity.onGetDataCompleted(TestActivity.java:23)
at com.frank.glidedemo.TestActivity.access$000(TestActivity.java:10)
at com.frank.glidedemo.TestActivity$BackgroundTask.onPostExecute(TestActivity.java:46)
at com.frank.glidedemo.TestActivity$BackgroundTask.onPostExecute(TestActivity.java:28)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)

解決辦法:正確管理Background Threads(異步線程),當Activity停止或銷燬時,停止所有相關的異步線程,停止所有後續的UI操作。或者加載前使用isFinishing()isDestroyed()進行限制(不建議這種處理方式)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章