1、在build.gradle中添加依賴:? ??
compile 'com.github.bumptech.glide:glide:3.7.0'
需要support-v4庫(kù)的支持,如果你的項(xiàng)目沒有support-v4庫(kù)(項(xiàng)目默認(rèn)已經(jīng)添加了)闸婴,還需要添加support-v4依賴:? ? ?
?compile'com.Android.support:support-v4:23.3.0'
2趾娃、然后配置混淆規(guī)則:
-keeppublicclass
?*implements
?com.bumptech.glide.module.GlideModule
-keeppublic
enum?
com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$**
?{
**[] $VALUES;
public *;
?}
其中第一個(gè)混淆規(guī)則表明不混淆所有的GlideModule奴愉。
?如果需要的話跃洛,還需添加相應(yīng)的權(quán)限:
3、 使用Glide.with(this).load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png").into(imageView);
Glide.with()
使用with(Context context). 使用Application上下文抵碟,Glide請(qǐng)求將不受Activity/Fragment生命周期控制。
with(Activity activity).使用Activity作為上下文坏匪,Glide的請(qǐng)求會(huì)受到Activity生命周期控制拟逮。with(FragmentActivity activity).Glide的請(qǐng)求會(huì)受到FragmentActivity生命周期控制。with(android.app.Fragment fragment).Glide的請(qǐng)求會(huì)受到Fragment 生命周期控制适滓。with(android.support.v4.app.Fragment fragment).Glide的請(qǐng)求會(huì)受到Fragment生命周期控制敦迄。
requestManager.load()
使用Glide基本可以load任何可以拿到的媒體資源,如:
?load SD卡資源:load("file://"+ Environment.getExternalStorageDirectory().getPath()+"/test.jpg") load assets資源:load("file:///android_asset/f003.gif") load raw資源:load("Android.resource://com.frank.glide/raw/raw_1")或load("android.resource://com.frank.glide/raw/"+R.raw.raw_1) load drawable資源:load("android.resource://com.frank.glide/drawable/news")或load("android.resource://com.frank.glide/drawable/"+R.drawable.news) load ContentProvider資源:load("content://media/external/images/media/139469") load http資源:load("http://cn.bing.com/az/hprichbg/rb/Dongdaemun_ZH-CN10736487148_1920x1080.jpg") load https資源:load(" http://cn.bing.com/az/hprichbg/rb/Dongdaemun_ZH-CN10736487148_1920x1080.jpg ")?
當(dāng)然凭迹,load不限于String類型罚屋,還可以:??
?load(Uri uri),load(File file)嗅绸,load(Integer resourceId)脾猛,load(URL url),load(byte[] model)鱼鸠,load(T model)猛拴,loadFromMediaStore(Uri uri)羹铅。?
load的資源也可以是本地視頻,如果想要load網(wǎng)絡(luò)視頻或更高級(jí)的操作可以使用VideoView等其它控件完成愉昆。?
而且可以使用自己的ModelLoader進(jìn)行資源加載:
? using(ModelLoadermodelLoader, ClassdataClass)职员,using(final StreamModelLoadermodelLoader),using(StreamByteArrayLoader modelLoader)撼唾,using(final FileDescriptorModelLoadermodelLoader)廉邑。?
返回GenericRequestBuilder實(shí)例。
GenericRequestBuilder使用
GenericRequestBuilder是最頂層的Request Builder倒谷,用于處理選項(xiàng)設(shè)置和開始一般resource類型資源的加載蛛蒙。其中ModelType是指代表資源的類型,如"http://img.my.csdn.net/uploads/201508/05/1438760757_3588.jpg"這個(gè)String就代表了一張圖片資源渤愁,所以這個(gè)ModelType就是String牵祟。DataType是指ModelLoader提供的,可以被ResourceDecoder解碼的數(shù)據(jù)類型抖格。ResourceType是指將要加載的resource類型诺苹。TranscodeType是指已解碼的資源將要被轉(zhuǎn)成的資源類型。
1雹拄、thumbnail(float sizeMultiplier). 請(qǐng)求給定系數(shù)的縮略圖收奔。如果縮略圖比全尺寸圖先加載完,就顯示縮略圖滓玖,否則就不顯示坪哄。系數(shù)sizeMultiplier必須在(0,1)之間,可以遞歸調(diào)用該方法势篡。
2翩肌、sizeMultiplier(float sizeMultiplier). 在加載資源之前給Target大小設(shè)置系數(shù)。
3禁悠、diskCacheStrategy(DiskCacheStrategy strategy).設(shè)置緩存策略念祭。DiskCacheStrategy.SOURCE:緩存原始數(shù)據(jù),DiskCacheStrategy.RESULT:緩存變換(如縮放碍侦、裁剪等)后的資源數(shù)據(jù)粱坤,DiskCacheStrategy.NONE:什么都不緩存,DiskCacheStrategy.ALL:緩存SOURC和RESULT瓷产。默認(rèn)采用DiskCacheStrategy.RESULT策略比规,對(duì)于download only操作要使用DiskCacheStrategy.SOURCE。
4拦英、priority(Priority priority). 指定加載的優(yōu)先級(jí)蜒什,優(yōu)先級(jí)越高越優(yōu)先加載,但不保證所有圖片都按序加載疤估。枚舉Priority.IMMEDIATE灾常,Priority.HIGH霎冯,Priority.NORMAL,Priority.LOW钞瀑。默認(rèn)為Priority.NORMAL沈撞。
5、dontAnimate(). 移除所有的動(dòng)畫雕什。
6缠俺、animate(int animationId). 在異步加載資源完成時(shí)會(huì)執(zhí)行該動(dòng)畫。
7贷岸、animate(ViewPropertyAnimation.Animator animator). 在異步加載資源完成時(shí)會(huì)執(zhí)行該動(dòng)畫壹士。
8、placeholder(int resourceId). 設(shè)置資源加載過程中的占位Drawable偿警。
9躏救、placeholder(Drawable drawable). 設(shè)置資源加載過程中的占位Drawable。
10螟蒸、fallback(int resourceId). 設(shè)置model為空時(shí)要顯示的Drawable盒使。如果沒設(shè)置fallback,model為空時(shí)將顯示error的Drawable七嫌,如果error的Drawable也沒設(shè)置少办,就顯示placeholder的Drawable。
11诵原、fallback(Drawable drawable).設(shè)置model為空時(shí)顯示的Drawable英妓。
12、error(int resourceId).設(shè)置load失敗時(shí)顯示的Drawable皮假。
13、error(Drawable drawable).設(shè)置load失敗時(shí)顯示的Drawable骂维。
14惹资、listener(RequestListenerrequestListener). 監(jiān)聽資源加載的請(qǐng)求狀態(tài),可以使用兩個(gè)回調(diào):onResourceReady(R resource, T model, Targettarget, boolean isFromMemoryCache, boolean isFirstResource)和onException(Exception e, T model, Target target, boolean isFirstResource)航闺,但不要每次請(qǐng)求都使用新的監(jiān)聽器褪测,要避免不必要的內(nèi)存申請(qǐng),可以使用單例進(jìn)行統(tǒng)一的異常監(jiān)聽和處理潦刃。
15侮措、skipMemoryCache(boolean skip). 設(shè)置是否跳過內(nèi)存緩存,但不保證一定不被緩存(比如請(qǐng)求已經(jīng)在加載資源且沒設(shè)置跳過內(nèi)存緩存乖杠,這個(gè)資源就會(huì)被緩存在內(nèi)存中)分扎。
16、override(int width, int height). 重新設(shè)置Target的寬高值(單位為pixel)胧洒。
17畏吓、into(Y target).設(shè)置資源將被加載到的Target墨状。
18、into(ImageView view). 設(shè)置資源將被加載到的ImageView菲饼。取消該ImageView之前所有的加載并釋放資源肾砂。
19、into(int width, int height). 后臺(tái)線程加載時(shí)要加載資源的寬高值(單位為pixel)宏悦。
20镐确、preload(int width, int height). 預(yù)加載resource到緩存中(單位為pixel)。
21饼煞、asBitmap(). 無論資源是不是gif動(dòng)畫源葫,都作為Bitmap對(duì)待。如果是gif動(dòng)畫會(huì)停在第一幀派哲。
22臼氨、asGif().把資源作為GifDrawable對(duì)待。如果資源不是gif動(dòng)畫將會(huì)失敗芭届,會(huì)回調(diào).error()储矩。
4、技巧
?1褂乍、禁止內(nèi)存緩存:? ?
?.skipMemoryCache(true)
2持隧、清除內(nèi)存緩存:? ?
?// 必須在UI線程中調(diào)用? ??
Glide.get(context).clearMemory();
3、禁止磁盤緩存:
? .diskCacheStrategy(DiskCacheStrategy.NONE)
4逃片、清除磁盤緩存:?
?// 必須在后臺(tái)線程中調(diào)用屡拨,建議同時(shí)clearMemory()? Glide.get(applicationContext).clearDiskCache();
5、獲取緩存大腥焓怠:?
new GetDiskCacheSizeTask(textView).execute(new File(getCacheDir(), DiskCache.Factory.DEFAULT_DISK_CACHE_DIR));11class GetDiskCacheSizeTask extends AsyncTask{
private final TextView resultView;
public GetDiskCacheSizeTask(TextView resultView) {
this.resultView = resultView;
}
@Override
protected void onPreExecute() {
resultView.setText("Calculating...");
}
@Override
protected void onProgressUpdate(Long... values) { /* onPostExecute(values[values.length - 1]); */ }
@Override
protected Long doInBackground(File... dirs) {
try {
long totalSize = 0;
for (File dir : dirs) {
publishProgress(totalSize);
totalSize += calculateSize(dir);
}
return totalSize;
} catch (RuntimeException ex) {
final String message = String.format("Cannot get size of %s: %s", Arrays.toString(dirs), ex);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
resultView.setText("error");
Toast.makeText(resultView.getContext(), message, Toast.LENGTH_LONG).show(); ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?return 0L;
}
@Override
protected void onPostExecute(Long size) {
String sizeText = android.text.format.Formatter.formatFileSize(resultView.getContext(), size);
resultView.setText(sizeText);
}
private static long calculateSize(File dir) {
if (dir == null) return 0;
if (!dir.isDirectory()) return dir.length();
long result = 0;
File[] children = dir.listFiles();
if (children != null)
for (File child : children)
result += calculateSize(child);
return result;}
}
6呀狼、指定資源的優(yōu)先加載順序:??
//優(yōu)先加載
? ? ?Glide
? ? ? ? ? ? ?.with(context)
? ? ? ? ? ? ?.load(heroImageUrl)
? ? ? ? ? ? .priority(Priority.HIGH)
? ? ? ? ? ? .into(imageViewHero);
//后加載
? ? ? ?Glide
? ? ? ? ? ? .with(context)
? ? ? ? ? ? .load(itemImageUrl)
? ? ? ? ? ?.priority(Priority.LOW)
? ? ? ? ? ? .into(imageViewItem);
7、先顯示縮略圖损离,再顯示原圖:? ?
//用原圖的1/10作為縮略圖? ? Glide? ? ? ?
?.with(this) ? ? ? ? ? ? ? ?.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png") ? ? ? ? .thumbnail(0.1f)? ? ? ? .into(iv_0);? ? //用其它圖片作為縮略圖 ? ? ? ?DrawableRequestBuilderthumbnailRequest = Glide
.with(this)
.load(R.drawable.news);
Glide.with(this)
.load("http://inthecheesefactory.com/uploads/source/nestedfragment/fragments.png")
.thumbnail(thumbnailRequest)
.into(iv_0);
8哥艇、對(duì)圖片進(jìn)行裁剪、模糊僻澎、濾鏡等處理:
?推薦使用獨(dú)立的圖片處理庫(kù):wasabeef/glide-transformations貌踏,使用也很簡(jiǎn)單:?
?? compile 'jp.wasabeef:glide-transformations:2.0.0'
之后我們就可以使用GenericRequestBuilder或其子類的transform()或bitmapTransform()方法設(shè)置圖片轉(zhuǎn)換了:? ?
?//圓形裁剪? ? 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); ? ?
//其它變換...
5、 Glide有哪些“坑”窟勃?
1祖乳、ImageView的setTag問題 問題描述: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??如果使用Glide的into(imageView)為ImageView設(shè)置圖片的同時(shí)使用ImageView的setTag(final Object tag)方法,將會(huì)導(dǎo)致java.lang.IllegalArgumentException: You must not call setTag() on a view Glide is targeting異常秉氧。因?yàn)镚lide的ViewTarget中通過view.setTag(tag)和view.getTag()標(biāo)記請(qǐng)求的眷昆,由于Android 4.0之前Tag存儲(chǔ)在靜態(tài)map里,如果Glide使用setTag(int key, final Object tag)方法標(biāo)記請(qǐng)求則可能會(huì)導(dǎo)致內(nèi)存泄露,所以Glide默認(rèn)使用view.setTag(tag)標(biāo)記請(qǐng)求隙赁,你就不能重復(fù)調(diào)用了垦藏。 解決辦法:如果你需要為ImageView設(shè)置Tag,必須使用setTag(int key, final Object tag)及getTag(int key)方法伞访,其中key必須是合法的資源ID以確保key的唯一性掂骏,典型做法就是在資源文件中聲明type="id"的item資源。
2厚掷、placeholder()導(dǎo)致的圖片變形問題 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?問題描述:使用.placeholder()方法在某些情況下會(huì)導(dǎo)致圖片顯示的時(shí)候出現(xiàn)圖片變形的情況弟灼。這是因?yàn)镚lide默認(rèn)開啟的crossFade動(dòng)畫導(dǎo)致的TransitionDrawable繪制異常,詳細(xì)描述和討論可以看一下這個(gè)#363 issue冒黑。根本原因就是你的placeholder圖片和你要加載顯示的圖片寬高比不一樣田绑,而Android的TransitionDrawable無法很好地處理不同寬高比的過渡問題,這的確是個(gè)Bug抡爹,是Android的也是Glide的掩驱。 解決辦法:使用.dontAnimate()方法禁用過渡動(dòng)畫,或者使用animate()方法自己寫動(dòng)畫冬竟,再或者自己修復(fù)TransitionDrawable的問題欧穴。
3、ImageView的資源回收問題 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 問題描述:默認(rèn)情況下泵殴,Glide會(huì)根據(jù)with()使用的Activity或Fragment的生命周期自動(dòng)調(diào)整資源請(qǐng)求以及資源回收涮帘。但是如果有很占內(nèi)存的Fragment或Activity不銷毀而僅僅是隱藏視圖,那么這些圖片資源就沒辦法及時(shí)回收笑诅,即使是GC的時(shí)候调缨。 解決辦法:可以考慮使用WeakReference,如:? ? final WeakReferenceimageViewWeakReference = new WeakReference<>(imageView);
ImageView target = imageViewWeakReference.get();
if (target != null) {
Glide.with(context).load(uri).into(target);
}
4吆你、ImageView的scaleType問題
scaleType默認(rèn)為fitCenter模式弦叶,如果你想設(shè)置成centerInside,不好意思妇多,3.x還沒有這個(gè)方法伤哺,參見這個(gè)#591 issue,折中的解決辦法就是放棄使用centerInside砌梆,或者結(jié)合android:scaleType="centerInside"和.dontTransform()使用以禁止Glide對(duì)資源進(jìn)行轉(zhuǎn)換默责。
如果你想要ImageView的寬高根據(jù)圖片資源的大小而定(即使用wrap_comtent)贬循,那么你就必須明確告訴Glide我想加載原始資源:使用android:scaleType="center"咸包,或者.dontTransform(),或者.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)杖虾。
不推薦使用fitXY烂瘫,因?yàn)檫@樣Glide會(huì)加載全尺寸圖像到內(nèi)存中而造成不必要的內(nèi)存占用。
5、異步線程完成后加載圖片的崩潰問題
問題描述:通常情況下坟比,異步線程會(huì)被約束在Activity生命周期內(nèi)芦鳍,所以異步線程完成后使用Glide加載圖片是沒有問題的。但如果你的異步線程在Activity銷毀時(shí)沒有取消掉葛账,那么異步線程完成后就Glide就無法為一個(gè)已銷毀的Activity加載圖片資源柠衅,拋出的異常如下(在with()方法中就進(jìn)行判斷并拋出異常):
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(異步線程),當(dāng)Activity停止或銷毀時(shí)籍琳,停止所有相關(guān)的異步線程菲宴,停止所有后續(xù)的UI操作∏骷保或者加載前使用isFinishing()或isDestroyed()進(jìn)行限制(不建議這種處理方式)喝峦。
6、由于Bitmap復(fù)用導(dǎo)致的在某些設(shè)備上圖片錯(cuò)亂的問題
問題描述: Glide默認(rèn)使用BitmapPool的方式對(duì)應(yīng)用中用到的Bitmap進(jìn)行復(fù)用呜达,以減少頻繁的內(nèi)存申請(qǐng)和內(nèi)存回收谣蠢,而且默認(rèn)使用的Bitmap模式為RGB565以減少內(nèi)存開銷。但在某些設(shè)備上(通常在Galaxy系列5.X設(shè)備上很容易復(fù)現(xiàn))某些情況下會(huì)出現(xiàn)圖片加載錯(cuò)亂的問題查近,具體詳見這個(gè)#601 issue眉踱。原因初步確定是OpenGL紋理渲染異常。
解決辦法:GlideModule使用PREFER_ARGB_8888(Glide4.X已經(jīng)默認(rèn)使用該模式了)嗦嗡,雖然內(nèi)存占用比RGB565更多一點(diǎn)勋锤,但可以更好地處理有透明度Bitmap的復(fù)用問題〗募溃或者禁用Bitmap復(fù)用setBitmapPool(new BitmapPoolAdapter())來修復(fù)這個(gè)問題(不推薦這種處理方式)
6叁执、Picasso和Glide的區(qū)別
1、Glide比Picasso加載速度快
2矮冬、默認(rèn)情況Glide更有利于減少OutOfMemoryError的發(fā)生谈宛,不過Picasso的圖片質(zhì)量更高
3、Glide支持gif胎署,Picasso不支持