學(xué)習(xí)來(lái)源:郭霖大師博客地址
1卢鹦、圖片加載框架挺多,如Volley劝堪、Glide冀自、Picasso、Fresco秒啦、本次是跟著郭大師學(xué)習(xí)Glide熬粗、做學(xué)習(xí)筆記。
2余境、首先添加Glide的依賴? compile 'com.github.bumptech.glide:glide:3.7.0'驻呐;或者eclipse下載glide3.7的jar包地址
3灌诅、使用Glide需要獲取網(wǎng)絡(luò)權(quán)限:<uses-permission android:name="android.permission.INTERNET">
4、Glide的使用:
1.基本調(diào)用:Glide.with(this).load(url).into(imageView);
with方法可以傳遞Context含末、Activity猜拾、Fragment,ApplicationContext類型的參數(shù)佣盒,with方法中傳遞的參數(shù)決定了Glide加載圖片的生命周期挎袜,如果傳遞的是Activity或者Fragment,那么此Activity或Fragment銷毀時(shí)肥惭,圖片加載會(huì)停止宋雏;如果傳遞的是ApplicationContext,那么只有程序停止時(shí)务豺,圖片加載會(huì)停止磨总。
load方式支持加載各種各樣的圖片資源,包括網(wǎng)絡(luò)圖片笼沥,本地圖片蚪燕,應(yīng)用資源,二進(jìn)制流奔浅,Url對(duì)象等馆纳,對(duì)應(yīng)有如下多個(gè)重載方式。
// 加載本地圖片F(xiàn)ile file = new File(getExternalCacheDir() + "/image.jpg")汹桦;? ? ? Glide.with(this).load(file).into(imageView);
// 加載應(yīng)用資源int resource = R.drawable.image;? ? ? ? ? ? ? ? ? ? Glide.with(this).load(resource).into(imageView);
// 加載二進(jìn)制流byte[] image = getImageBytes();? ? ? ? ? ? ? ? ? ? ??Glide.with(this).load(image).into(imageView);
// 加載Uri對(duì)象Uri imageUri = getImageUri();? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Glide.with(this).load(imageUri).into(imageView);
into方法傳遞的參數(shù)可以是ImageView的實(shí)例鲁驶,也可以是其他類型的參數(shù),后邊學(xué)習(xí)舞骆。
?2.占位圖的使用
圖片加載需要一定的時(shí)間钥弯,特別是第一次加載圖片時(shí),所以需要先給圖片一個(gè)默認(rèn)圖片督禽,即占位圖脆霎,等圖片加載完成后會(huì)被替換。
使用方法placeholder方法:Glide.with(this).load(url).placeholder(R.drawable.loading).into(imageView)狈惫。
3.異常占位圖
圖片加載可能存在失敗的情況睛蛛,所以需要設(shè)置一個(gè)異常占位圖,在加載失敗場(chǎng)景下顯示胧谈。
使用error方法:Glide.with(this).load(url).placeholder(R.drawable.loading).error(R.drawable.error).into(imageView)忆肾。
4.指定圖片的格式
Glide可以加載GIF圖片,不需要特殊的設(shè)置菱肖,它會(huì)自行判斷客冈,所以使用上述的方式傳入一個(gè)GIF的Url即可加載。
如果我們需要加載的就是一個(gè)靜態(tài)圖蔑滓,不需要Glide自行判斷郊酒,可以代碼設(shè)置加載圖片類型遇绞。
加載靜態(tài)圖片:Glide.with(this).load(url).asBitmap()....? ?如果實(shí)際傳入的是GIF圖片,那么會(huì)加載顯示GIF圖片的第一幀
加載動(dòng)態(tài)圖片:Glide.with(this).load(url).asGif()......? ? 如果實(shí)際傳入的是靜態(tài)圖片燎窘,那么會(huì)加載失敗摹闽,顯示異常占位圖
5.設(shè)置圖片的大小
圖片造成的內(nèi)存浪費(fèi),圖片的實(shí)際尺寸的像素大于ImageView所需要的像素尺寸褐健。
使用Glide則不需要考慮內(nèi)存的浪費(fèi)付鹿,甚至是內(nèi)存溢出的問(wèn)題,Glide會(huì)自動(dòng)判斷ImageView的大小蚜迅,加載合適的尺寸到內(nèi)存中舵匾。
當(dāng)然也可以設(shè)置加載圖片的大小忽略ImageView的實(shí)際大小。使用方法override:Glide.with(this).load(uri).override(100,100)....谁不。
6.源碼地址
Glide的GitHub主頁(yè)的地址是:https://github.com/bumptech/glide?這個(gè)看到的始終是最新的
Glide的3.7.0版本源碼地址:https://github.com/bumptech/glide/tree/v3.7.0
7.Glide緩存
Glide的緩存設(shè)計(jì)既考慮的內(nèi)存緩存也考慮了硬盤(pán)緩存坐梯,內(nèi)存緩存的目的是為了防止應(yīng)用重復(fù)講圖片的數(shù)據(jù)讀取到內(nèi)存中,硬盤(pán)緩存是為了防止應(yīng)用重復(fù)從網(wǎng)絡(luò)或其他地方重復(fù)下載和讀取數(shù)據(jù)刹帕。
緩存的Key使用了多個(gè)參數(shù)結(jié)合吵血,寬高不一樣也會(huì)造成可以值不同。
內(nèi)存緩存:Glide默認(rèn)開(kāi)啟內(nèi)存緩存偷溺,即內(nèi)存的數(shù)據(jù)沒(méi)有被清除之前蹋辅,不需要從硬盤(pán)或者網(wǎng)絡(luò)上讀取,提高了加載速度和用戶體驗(yàn)挫掏,當(dāng)然Glide也可以禁止使用內(nèi)存緩存侦另,使用skipMemoryCache(true):Glide.wit(this).load(uri).skipMemoryCacge(true).into(imageView)。
Glide內(nèi)存緩存的實(shí)現(xiàn)尉共,主要使用了LruCache算法(Least Recently Used),即最近最少使用算法褒傅,除了LRUCache算法之外,Glide還用到了弱引用機(jī)制爸邢,共同完成內(nèi)存緩存功能樊卓。
硬盤(pán)緩存:Glide默認(rèn)開(kāi)啟硬盤(pán)緩存,如果需要禁止硬盤(pán)緩存杠河,使用diskCacheStrategy(DiskCacheStrategy.NONE)。?diskCacheStrategy提供了四種參數(shù):? ? ? ??
DiskCacheStrategy.NONE: 表示不緩存任何內(nèi)容浇辜。?? ? ?
DiskCacheStrategy.SOURCE: 表示只緩存原始圖片券敌。
DiskCacheStrategy.RESULT: 表示只緩存轉(zhuǎn)換過(guò)后的圖片(默認(rèn)選項(xiàng))。
DiskCacheStrategy.ALL : 表示既緩存原始圖片柳洋,也緩存轉(zhuǎn)換過(guò)后的圖片待诅。
Glide默認(rèn)不會(huì)將原始圖片展示出來(lái),而是會(huì)對(duì)圖片進(jìn)行壓縮和轉(zhuǎn)換熊镣。硬盤(pán)緩存的實(shí)現(xiàn)也是利用LruCache算法卑雁,而且Google也提供了一個(gè)工具類DiskCache募书,
緩存問(wèn)題之緩存失效:有的url地址會(huì)在圖片的url地址上添加一個(gè)token參數(shù),做保護(hù)驗(yàn)證测蹲,但是token可能會(huì)變導(dǎo)致緩存視效莹捡,例如http://url.com/image.jpg?token=d9caa6e02c990b0a。問(wèn)題原因是token變了扣甲,圖片傳入的url變了篮赢,緩存的key也跟著變了,導(dǎo)致緩存失效琉挖,解決的方法是理解緩存key的構(gòu)造启泣,重寫(xiě)GlideUrl的getCacheKey()方法,在此方法中將傳入的url的token過(guò)濾掉示辈,這樣不管token怎樣變寥茫,緩存key是不變的。
8.into方法的深入學(xué)習(xí)
Glide的into方法不止可以傳遞ImageView對(duì)象矾麻,也可以傳遞Glide的一個(gè)內(nèi)部Target對(duì)象坠敷,實(shí)現(xiàn)target接口的對(duì)象有很多,主要使用的是SimpleTarget和ViewTarget射富。
SimpleTarget使用膝迎,如下繼承SimpleTarget,重寫(xiě)onResourceReady方法胰耗,此方法中的回調(diào)傳遞了圖片對(duì)象的實(shí)例限次,如果確認(rèn)加載的圖片不是一個(gè)GIF圖片,可以指定SimpTarget的泛型為Bitmap對(duì)象柴灯。
SimpleTarget simpleTarget = new SimpleTarget() {
? ? @Override? ? public void onResourceReady(GlideDrawable resource, GlideAnimation glideAnimation) {
? ? ? ? imageView.setImageDrawable(resource);
? ? }
};
ViewTarget使用卖漫,Gilde默認(rèn)創(chuàng)建的是GlideDrawableImageVIewTarget就是ViewTarget的子類,被限制只能作用于ImageView赠群。而ViewTarget的功能更加廣泛羊始,作用于任何View。例如:自定義布局查描,在布局內(nèi)自定義ViewTarget突委,在onResourceReady回調(diào)中給此布局設(shè)置背景,這樣通過(guò)Glide即可以傳遞自定義布局的Target對(duì)象冬三。
public classMyLayoutextendsLinearLayout{ private ViewTarget viewTarget;
? ? public MyLayout(Context context, AttributeSet attrs) {
? ? ? ? super(context, attrs);
? ? ? ? viewTarget = new ViewTarget(this) {
? ? ? ? ? ? @Override? ? ? ? ? ? public void onResourceReady(GlideDrawable resource, GlideAnimation glideAnimation) {
? ? ? ? ? ? ? ? MyLayout myLayout = getView();
? ? ? ? ? ? ? ? myLayout.setImageAsBackground(resource);
? ? ? ? ? ? }
? ? ? ? };
? ? }
? ? public ViewTarget getTarget() {
? ? ? ? return viewTarget;
? ? }
? ? public void setImageAsBackground(GlideDrawable resource) {
? ? ? ? setBackground(resource);
? ? }
}
調(diào)用方式:Glide.with(this).load(url).into(myLayout.getTarget());
9.preload()方法
Glide可以使用reload方法實(shí)現(xiàn)預(yù)加載功能匀油,使用方式是:Glide.with(this).load(url).diskCacheStrategy(DiskCacheStrategy.SOURCE).preload(),即會(huì)加載原生的圖片到緩存中勾笆;使用的時(shí)候:Glide.whit(this).load(uri).diskCacehStrategy(DiskCacheStrategy.SOURCE).into(imageView)敌蚜。特殊說(shuō)明使用Strategy.SOURCE指定緩存的對(duì)象是原生圖片,因?yàn)閜reload默認(rèn)緩存的就是原始圖片窝爪,而into默認(rèn)的是根據(jù)imageView大小動(dòng)態(tài)調(diào)整的大小弛车,如果不指定緩存方式齐媒,會(huì)導(dǎo)致into重新從網(wǎng)上獲取圖片,預(yù)加載功能失效纷跛。
preload有兩個(gè)重載方法喻括,不傳遞參數(shù)代碼緩存原始圖片大小,傳遞參數(shù)可以指定緩存圖片的寬高忽舟。
10.downloadOnly()方法
downloadOnly只下載圖片双妨,不會(huì)對(duì)圖片進(jìn)行加載,下載完之后我們可以獲取圖片的存儲(chǔ)路徑叮阅,進(jìn)行后續(xù)操作刁品。downloadOnly有兩個(gè)重載方法。
downloadOnly(int width,int height)? 用于子線程下載圖片浩姥,原因返回的FureTarget的對(duì)象的get方法會(huì)在子線程中等待圖片下載完成才返回結(jié)果挑随,如果下載原生圖片傳遞Target.SIZE.ORIGINAL即可。使用方法:FutureTarget target = Glide.with(getApplicationContext()).load(url).downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);? ? ? File imagFile = target.get();之后我們可以采用如下方法加載這張圖片勒叠。Glide.with(this).load(url).diskCacheStrategy(DiskCacheStrategy.SOURCE).into(imageView); 注意緩存的策略必須知道加載方式為DiskCacheStrategy.SOURCE或者DiskCacheStrategy.ALL兜挨,否則Glide將無(wú)法使用剛才下載好的圖片緩存文件。
downloadOnly(Y target) 用于在主線程下載圖片眯分。傳遞的target需要我們自己去實(shí)現(xiàn)拌汇,注意target的泛型必現(xiàn)指定為FIle類型,主要是實(shí)現(xiàn)兩個(gè)方法弊决,一個(gè)是getSize()方法噪舀,一個(gè)是onResourceReady()方法。getSize()中返回計(jì)算圖片的大小飘诗,onResourceReady()回調(diào)方法的參數(shù)有我們需要的File對(duì)象可以供我們后續(xù)使用与倡。使用方式Glide.with(this)?.load(url).downloadOnly(new DownloadImageTarget());
11.listener()方法
Glide的監(jiān)聽(tīng)圖片加載狀態(tài),是否成功或者失敗昆稿,可以使用Listener()方法監(jiān)聽(tīng)纺座,使用方式:Glide.with(this).load(uri)..listener(new RequestListener() {..onException()..onResourceReady().}).into(imageView)。其中onException()是加載失敗的回調(diào)溉潭,onResourceReady是加載成功的回調(diào)净响。兩個(gè)函數(shù)的返回值如果是false則不消費(fèi)時(shí)間,會(huì)繼續(xù)向下傳遞到setErrorPlaceholder()和Target的onResourceReady()方法岛抄。如果返回true則消費(fèi)事件别惦,對(duì)應(yīng)的不會(huì)向下傳遞事件。
12.dontTransform()方法
Glide加載圖片時(shí)會(huì)對(duì)圖片進(jìn)行變化夫椭,如果目標(biāo)的ImageView是wrap_content,默認(rèn)scaleType是FIT_CENTER熟悉氯庆,這樣加載圖片會(huì)進(jìn)行變化導(dǎo)致加載不是我們預(yù)期的加載原圖蹭秋∪鸥叮可以通過(guò)設(shè)置dontTransform來(lái)實(shí)現(xiàn)。Glide.with(this).load(uri).dontTransform().into(image); 調(diào)用此方法圖片的變化操作失效仁讨,如果需要變化操作可以使用override方法指定圖片的寬高羽莺。
13.圖片變化的基本使用
Glide圖片變化使用transform方法,Glide內(nèi)置了兩種圖片操作洞豁,我們可以直接使用:centerCrop和fitCenter盐固,兩個(gè)方法實(shí)際也是通過(guò)transform方法來(lái)實(shí)現(xiàn)的。其中fitCenter:Glide.with(this).load(uri).fitCenter().into(imageView) 會(huì)按照原生比例充滿屏幕丈挟,centerCrop:Glide.with(this).load(uri).centerCrop().into(imageView) 會(huì)對(duì)原圖中心區(qū)域進(jìn)行剪裁充滿屏幕的圖片刁卜,也看配合override方法指定剪裁的比例。
自定義圖片變化功能曙咽,其實(shí)就是基礎(chǔ)BitmapTransformation, 然后重寫(xiě)tranform方法蛔趴,和getId方法,其他getId要求返回唯一一個(gè)字段例朱,以和其他圖片變化做區(qū)分孝情。BitmapTransformation只能對(duì)靜態(tài)圖片進(jìn)行變化,如果是Gif圖片洒嗤,需要自己實(shí)現(xiàn)Transformation接口箫荡。使用方式:Glide.with(this).load(uri).transform(new BitmapTransformation({})).into(imageView)。
圖片轉(zhuǎn)換目前有很多的開(kāi)源庫(kù)渔隶,都是通用的羔挡,地址:glide-transformations的項(xiàng)目主頁(yè)地址是?https://github.com/wasabeef/glide-transformations?。使用: compile 'jp.wasabeef:glide-transformations:2.0.2'
14.自定義模塊的基本用法
自定義模塊功能可以更改Glide的配置派撕,使用方式是自定義模塊類實(shí)現(xiàn)GlideModule接口婉弹。重寫(xiě)applyOptions()方法和registerCompontes()方法。用于更改Glide的配置和替換Glide的組件终吼。前提要是Glide識(shí)別我們自定義的模塊镀赌,需要在<application>標(biāo)簽中加入一個(gè)meta-data配置項(xiàng),其中android:name指定成我們自定義的MyGlideModule的完整路徑际跪,android:value必須指定成GlideModule商佛,這個(gè)是固定值。
Glide常見(jiàn)的配置:
setMemoryCache()? ??用于配置Glide的內(nèi)存緩存策略姆打,默認(rèn)配置是LruResourceCache良姆。
setBitmapPool()? ? ? ?用于配置Glide的Bitmap緩存池,默認(rèn)配置是LruBitmapPool幔戏。
setDiskCache()? ? ? ? 用于配置Glide的硬盤(pán)緩存策略玛追,默認(rèn)配置是InternalCacheDiskCacheFactory。
setDiskCacheService()? ?用于配置Glide讀取緩存中圖片的異步執(zhí)行器,默認(rèn)配置是FifoPriorityThreadPoolExecutor痊剖,也就是先入先出原則韩玩。
setResizeService()? ?用于配置Glide讀取非緩存中圖片的異步執(zhí)行器,默認(rèn)配置也是FifoPriorityThreadPoolExecutor陆馁。
setDecodeFormat()? 用于配置Glide加載圖片的解碼模式找颓,默認(rèn)配置是RGB_565。
替換Glide組件叮贩;例如將Glide默認(rèn)的HttpURLConnection改為OkHttp:1.新建一個(gè)OkHttpFetcher類击狮,并且同樣實(shí)現(xiàn)DataFetcher接口;2.新建一個(gè)OkHttpGlideUrlLoader類,并且實(shí)現(xiàn)ModelLoader接口;3.注冊(cè)到Glide當(dāng)中益老,將原來(lái)的HTTP通訊組件給替換掉glide.register(GlideUrl.class, InputStream.class, new OkHttpGlideUrlLoader.Factory());
更簡(jiǎn)單的組件替換
Glide官方給我們提供了非常簡(jiǎn)便的HTTP組件替換方式彪蓬。并且除了支持OkHttp3之外,還支持OkHttp2和Volley杨箭。只需要在gradle添加配置即可:OkHttp3{ compile 'com.squareup.okhttp3:okhttp:3.9.0'? ? compile 'com.github.bumptech.glide:okhttp3-integration:1.5.0@aar'}寞焙;?OkHttp2{compile 'com.github.bumptech.glide:okhttp-integration:1.5.0@aar'? ? ?compile 'com.squareup.okhttp:okhttp:2.7.5'};Volley{compile 'com.github.bumptech.glide:volley-integration:1.5.0@aar'????????compile 'com.mcxiaoke.volley:library:1.0.19'}互婿。
15.帶進(jìn)度的Glide圖片加載
地址:http://blog.csdn.net/guolin_blog/article/details/78357251
16.Glide4
使用:implementation 'com.github.bumptech.glide:glide:4.4.0'? ?annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0' AndroidManifest申請(qǐng)網(wǎng)絡(luò)權(quán)限捣郊。
加載圖片: Glide.with(this).load(url).into(imageView); 與Glide3一樣
占位圖、指定圖片大小慈参、緩存機(jī)制呛牲、圖片轉(zhuǎn)換:
RequestOptions options = new RequestOptions().placeholder(R.drawable.ic_launcher_background).error(R.drawable.error).diskCacheStrategy(DiskCacheStrategy.NONE).override(Target.SIZE_ORIGINAL).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE) .transforms(...);
Glide.with(this).load(uri).apply(options).into(imageView);與GLide3區(qū)別多了RequestOptions對(duì)象驮配,支持多個(gè)配置調(diào)用娘扩。
指定格式:與Glide3一樣,asBitmap()壮锻,asGif()琐旁,新增asFile()方法和asDrawable()方法
listener()方法:實(shí)現(xiàn)RequestListener監(jiān)聽(tīng),回調(diào)onLoadFailed方法onResourceReady方法
Submit方法 相當(dāng)于Glide3的downloadOnly方法
自定義模塊:自定義模塊與Glide3基本一樣猜绣,差別在于Glide4不需要在AndroidManifest.xml注冊(cè)了灰殴。Glide4加入了@GlideModule的注解可以讓Glide識(shí)別自定義模塊。