詳解Android?GLide圖片加載常用幾種方法
緩存淺析
為啥要做緩存? android默認(rèn)給每個應(yīng)用只分配16M的內(nèi)存,所以如果加載過多的圖片,為了 防止內(nèi)存溢出 ,應(yīng)該將圖片緩存起來。
圖片的三級緩存分別是:
- 1、內(nèi)存緩存
- 2、本地緩存
- 3、網(wǎng)絡(luò)緩存 其中,內(nèi)存緩存應(yīng)優(yōu)先加載,它速度最快;本地緩存次優(yōu)先加載,它速度也快;網(wǎng)絡(luò)緩存不應(yīng)該優(yōu)先加載,它走網(wǎng)絡(luò),速度慢且耗流量。
最優(yōu)-優(yōu)先級:內(nèi)存緩存 > 本地緩存 > 網(wǎng)絡(luò)緩存
- 兩個方法實現(xiàn):根據(jù)圖片的url去加載圖片、在本地和內(nèi)存中緩存
- 兩個方法實現(xiàn):設(shè)置本地緩存,以及獲取本地緩存
- 兩個方法實現(xiàn):設(shè)置內(nèi)存緩存,獲取內(nèi)存緩存。
如果使用hashmap去存儲圖片時,當(dāng)圖片越來越多,那么會造成內(nèi)存溢出,因為是強(qiáng)引用(對于強(qiáng)引用的系統(tǒng)不會回收)
如果改成軟引用softReference,在android 2.3 以上的系統(tǒng),對象會被提前回收。
可以用LruCache來解決上述內(nèi)存不回收或提前回收的問題。least recentlly use 最少最近使用算法 它會將內(nèi)存控制在一定的大小內(nèi), 超出最大值時會自動回收, 這個最大值開發(fā)者自己定。(這個東西沒有用過..)
GLide圖片加載方法
圖片加載周期
Glide最簡單的用法:
Glide.with(context).load(url).into(imageView)
with()方法中傳入的Context實例會決定Glide加載圖片的生命周期,如果傳入的是Activity或者Fragment的實例,那么當(dāng)這個Activity或Fragment被銷毀的時候,圖片加載也會停止。如果傳入的是ApplicationContext,那么只有當(dāng)應(yīng)用程序被殺掉的時候,圖片加載才會停止。
想法:傳入ImageView.getContext()實例是不是最好的方案,ImageView所在的Context銷毀了,圖片自然應(yīng)該取消加載。此方案是否可行?列表的回收機(jī)制會不會有問題?
結(jié)論:不是最好的方案,fragment和adapter中ImageView.getContext()返回的都是Activity,當(dāng)fragment或adapter銷毀但activity并沒有銷毀時,圖片仍會加載,所以聲明周期并不合理
圖片格式(Bitmap,Gif)
Glide是支持加載GIF圖片的,不需要編寫額外的代碼,Glide內(nèi)部會自動判斷圖片格式(Gif圖不一定是以.gif后綴結(jié)尾的哦。
當(dāng)然也可以手動指定圖片格式: 調(diào)用了asBitmap()方法,靜態(tài)圖正常加載,GIF圖無法正常播放,會在界面上顯示第一幀的圖片; 調(diào)用了asGif()方法,GIF圖正常加載和播放,靜態(tài)圖加載失敗。
想法:一般情況下不需要指定圖片格式,動圖的播放機(jī)制(一直循環(huán)播放/只播放一次)怎么設(shè)置?默認(rèn)是循環(huán)播放
結(jié)論:設(shè)置監(jiān)聽,回調(diào)中設(shè)置播放次數(shù),如下:
Glide.with(this)
.load(url)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(
@Nullable GlideException e, Object model,
Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource,
Object model, Target<Drawable> target,
DataSource dataSource,
boolean isFirstResource) {
if (resource instanceof GifDrawable) {
//設(shè)置播放次數(shù)
((GifDrawable) resource).setLoopCount(3);
}
return false;
}
})
.into(iv);
緩存
在緩存這一功能上,Glide又將它分成了兩個模塊,一個是內(nèi)存緩存,一個是硬盤緩存。 默認(rèn)情況下,Glide自動就是開啟內(nèi)存緩存和磁盤緩存的。 磁盤緩存是存在哪的?是否需要動態(tài)權(quán)限,未授權(quán)時磁盤緩存是不是就失效了?
結(jié)論:磁盤緩存默認(rèn)存儲在應(yīng)用內(nèi)部文件,訪問應(yīng)用內(nèi)部文件無需動態(tài)申請權(quán)限
集成網(wǎng)絡(luò)框架
Glide默認(rèn)使用的是HttpUrlConnection,支持集成Volley,Okhttp等其它網(wǎng)絡(luò)棧。 想法:一般用的時候沒有集成過網(wǎng)絡(luò)棧,如何集成?
權(quán)限
一般使用場景是加載網(wǎng)絡(luò)圖片,Internet權(quán)限肯定是要的,但還有個小細(xì)節(jié):如果你正在從 URL 加載圖片,Glide 可以自動幫助你處理片狀網(wǎng)絡(luò)連接:它可以監(jiān)聽用戶的連接狀態(tài)并在用戶重新連接到網(wǎng)絡(luò)時重啟之前失敗的請求。如果 Glide 檢測到你的應(yīng)用擁有 ACCESS_NETWORK_STATE 權(quán)限,Glide 將自動監(jiān)聽連接狀態(tài)而不需要額外的改動。
占位符
- placeHolder
- error
- fallback
占位圖是否會影響控件的大??? 結(jié)論:不會,網(wǎng)上有人說會有問題,我用的Glide4.9版本試的,可能Glide已經(jīng)修復(fù)了
淡入效果
transitionOption
變換
縮放模式適配不同場景:
啟動頁/廣告頁
全屏展示(填充寬高),不變形,盡可能少的裁剪內(nèi)容[我特地問了做設(shè)計的朋友,他們是有設(shè)計規(guī)范的,四周不會放內(nèi)容,xx像素內(nèi)是內(nèi)容區(qū)域。所以適當(dāng)?shù)牟眉舻暨吷系膬?nèi)容是沒有問題的]。使用centerCrop就可滿足上述條件。
banner
banner一般都是以ViewPager做容器,ViewPager的高度是不支持wrap_content的,也就是說要么指定高度,要么match_parent。banner的寬一般是固定的,高度若是寫死,采用fitXY在有些手機(jī)上會有變形;fitCenter周邊可能會有留白;centerCrop又會裁剪掉邊上的內(nèi)容 (banner一般要求不能裁剪,本來區(qū)域就不大,你還裁剪,可能會丟失重要內(nèi)容)。
寬固定,高根據(jù)圖片比例算出控件高,設(shè)置給ViewPager,因為viewPager會預(yù)加載兩邊的view,所以適配的前提是所有banner圖片寬高比一致(一般都能滿足)
Glide.with(context)
.load(url)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
//根據(jù)圖片寬高比設(shè)置容器的高度
int intrinsicWidth = resource.getIntrinsicWidth();
int intrinsicHeight = resource.getIntrinsicHeight();
int height = intrinsicHeight * width / intrinsicWidth;
layoutParams.height = height;
return false;
}
})
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.transform(new RoundedCorners(10))
.into(imageView);固定寬高
圖片不變形,不裁剪,fitCenter即可滿足。
圓角
RoundedCorners
圓形
CircleCrop
不得不說Glide的設(shè)計真的滿足了我們99%的場景需求了。

以上是許多大廠中喜歡使用的圖片加載方法,這里簡單的舉例Glide圖片加載的幾種方案。其中阿里企業(yè)就是使用Glide圖片加載。有關(guān)更多Android技術(shù)詳解,和更多核心進(jìn)階技術(shù)。
總結(jié)
Glide是Android開發(fā)中常用的圖片框架,其最基本用法例如Glide.with(context).load(url).into(imageView),我們沿著此鏈?zhǔn)秸{(diào)用的順序一窺Glide圖片加載流程的樣貌。
一圖勝千言

以上就是詳解Android GLide圖片加載常用幾種方法的詳細(xì)內(nèi)容,更多關(guān)于Android GLide圖片加載的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)之微信底部菜單欄實現(xiàn)的幾種方法匯總
這篇文章主要介紹了Android開發(fā)之微信底部菜單欄實現(xiàn)的幾種方法,下面小編把每種方法通過實例逐一給大家介紹,需要的朋友可以參考下2016-09-09
RecyclerView+PagerSnapHelper實現(xiàn)抖音首頁翻頁的Viewpager效果
這篇文章主要為大家詳細(xì)介紹了RecyclerView+PagerSnapHelper實現(xiàn)抖音首頁翻頁的Viewpager效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-10-10
Android進(jìn)度條ProgressBar的實現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android進(jìn)度條ProgressBar的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
Android利用Flutter實現(xiàn)立體旋轉(zhuǎn)效果
本文主要介紹了Flutter繪圖如何使用ImageShader填充圖形,并且利用 Matrix4的三維變換加上動畫實現(xiàn)了立體旋轉(zhuǎn)的動畫效果,感興趣的可以嘗試一下2022-06-06
Android仿知乎懸浮功能按鈕FloatingActionButton效果
前段時間在看屬性動畫,恰巧這個按鈕的效果可以用屬性動畫實現(xiàn),下面通過本文給大家分享adroid仿知乎懸浮功能按鈕FloatingActionButton效果,需要的朋友參考下吧2017-04-04
Android 使用ContentObserver監(jiān)聽數(shù)據(jù)庫內(nèi)容是否更改
這篇文章主要介紹了Android 使用ContentObserver監(jiān)聽數(shù)據(jù)庫內(nèi)容是否更改的相關(guān)資料,ContentObserver內(nèi)容觀察者,目的是觀察(捕捉)特定Uri引起的數(shù)據(jù)庫的變化,需要的朋友可以參考下2017-08-08

