Android 平滑圖片加載和緩存庫 Glide 使用詳解

現(xiàn)在市面上知名的圖片加載庫有UIL,Picasso,Volley ImageLoader,Fresco以及我們今天的主角Glide。它們各有千秋,不能評定誰一定比誰好,只能說哪一個更適合你。

Universal Image Loader:一個強大的圖片加載庫,包含各種各樣的配置,最老牌,使用也最廣泛。
Picasso: Square出品,必屬精品。和OkHttp搭配起來更配呦!
Volley ImageLoader:Google官方出品,可惜不能加載本地圖片~
Fresco:Facebook出的,天生驕傲!不是一般的強大。
Glide:Google推薦的圖片加載庫,專注于流暢的滾動。

初試Glide

下面進入今天的主題,相信之前很多同學(xué)都看到過這篇介紹Glide的文章,中文版在這里。文中從各個方面介紹和比較了Glide與Picasso,總體來說二者極為相似,有著近乎相同的API的使用風(fēng)格。但Glide在緩存策略和加載GIF方面略勝一籌。最后作者也極力推薦了這個庫。
而且據(jù)說在Google新出的Photos應(yīng)用中,到處可見Glide的蹤跡。看到這里,你是不是已經(jīng)迫不及待的想試一試這個庫呢?就在你下定決心嘗試一記的時候,你又聽說Yelp app(據(jù)說是美國的大眾點評)也在使用這個吊炸天的庫。你的心中激動萬分,發(fā)四一定要使用這個庫。說干就干,打開Android Studio,在builde.gradle里面添加上

repositories {
  mavenCentral() // jcenter() works as well because it pulls from Maven Central
}

dependencies {
  compile 'com.github.bumptech.glide:glide:3.7.0'
  compile 'com.android.support:support-v4:19.1.0'
}

然后全局搜索圖片加載的地方,全部換成了下面的代碼:

Glide.with(mContext)
        .load(url)
        .placeholder(R.drawable.loading_spinner)
        .crossFade()
        .into(myImageView);

在經(jīng)過漫長的編譯過程之后,再次打開APP,看到有著漸現(xiàn)效果的圖片呈現(xiàn)在你的面前,你不禁叫道:“wocao,真TM帥!為什么我以前沒有發(fā)現(xiàn)呢?”。
不過在你使用了幾天之后你會發(fā)現(xiàn)一些問題:
為什么 有的圖片第一次加載的時候只顯示占位圖,第二次才顯示正常的圖片呢?
為什么 我總會得到類似You cannot start a load for a destroyed activity這樣的異常呢?
為什么 我不能給加載的圖片setTag()呢?
為什么?為什么?這么NB的庫竟然會有這么多的問題。沒錯,這就是我今天要講的重點。怎么避免上面的問題發(fā)生。

一些解決方案

1.如果你剛好使用了這個圓形Imageview庫或者其他的一些自定義的圓形Imageview,而你又剛好設(shè)置了占位的話,那么,你就會遇到第一個問題。如何解決呢?
方案一: 不設(shè)置占位;
方案二:使用Glide的Transformation API自定義圓形Bitmap的轉(zhuǎn)換。這里是一個已有的例子;
方案三:使用下面的代碼加載圖片:

Glide.with(mContext)
    .load(url) 
    .placeholder(R.drawable.loading_spinner)
    .into(new SimpleTarget<Bitmap>(width, height) {
        @Override 
        public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
            // setImageBitmap(bitmap) on CircleImageView 
        } 
    };

2.至于第二個問題,請記住一句話:不要再非主線程里面使用Glide加載圖片,如果真的使用了,請把context參數(shù)換成getApplicationContext。更多的細(xì)節(jié)請參考這個issue。
3.為什么不能設(shè)置Tag,是因為你使用的姿勢不對哦。如何為ImageView設(shè)置Tag呢?且聽我細(xì)細(xì)道來。
方案一:使用setTag(int,object)方法設(shè)置tag,具體用法如下:
Java代碼是醬紫的:

Glide.with(context).load(urls.get(i).getUrl()).fitCenter().into(imageViewHolder.image);
        imageViewHolder.image.setTag(R.id.image_tag, i);
        imageViewHolder.image.setOnClickListener(new View.OnClickListener() {
            @Override
                int position = (int) v.getTag(R.id.image_tag);
                Toast.makeText(context, urls.get(position).getWho(), Toast.LENGTH_SHORT).show();
            }
        });

同時在values文件夾下新建ids.xml,添加

<item name="image_tag" type="id"/>

大功告成!
方案二:從Glide的3.6.0之后,新添加了全局設(shè)置的方法。具體方法如下:
先實現(xiàn)GlideMoudle接口,全局設(shè)置ViewTaget的tagId:

public class MyGlideMoudle implements GlideModule{
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        ViewTarget.setTagId(R.id.glide_tag_id);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {

    }
}

同樣,也需要在ids.xml下添加id

<item name="glide_tag_id" type="id"/>

最后在AndroidManifest.xml文件里面添加

<meta-data
    android:name="com.yourpackagename.MyGlideMoudle"
    android:value="GlideModule" />

又可以愉快的玩耍了,嘻嘻`(∩_∩)′。
方案三:寫一個繼承自ImageViewTaget的類,復(fù)寫它的get/setRequest方法。

Glide.with(context).load(urls.get(i).getUrl()).fitCenter().into(new ImageViewTarget<GlideDrawable>(imageViewHolder.image) {
            @Override
            protected void setResource(GlideDrawable resource) {
                imageViewHolder.image.setImageDrawable(resource);
            }

            @Override
            public void setRequest(Request request) {
                imageViewHolder.image.setTag(i);
                imageViewHolder.image.setTag(R.id.glide_tag_id,request);
            }

            @Override
            public Request getRequest() {
                return (Request) imageViewHolder.image.getTag(R.id.glide_tag_id);
            }
        });

        imageViewHolder.image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = (int) v.getTag();
                Toast.makeText(context, urls.get(position).getWho(), Toast.LENGTH_SHORT).show();
            }
        });
一些使用技巧

1.Glide.with(context).resumeRequests()和 Glide.with(context).pauseRequests()
當(dāng)列表在滑動的時候,調(diào)用pauseRequests()取消請求,滑動停止時,調(diào)用resumeRequests()恢復(fù)請求。這樣是不是會好些呢?
2.Glide.clear()
當(dāng)你想清除掉所有的圖片加載請求時,這個方法可以幫助到你。
3.ListPreloader
如果你想讓列表預(yù)加載的話,不妨試一下ListPreloader這個類。

一些基于Glide的優(yōu)秀庫

1.glide-transformations(https://github.com/wasabeef/glide-transformations)
一個基于Glide的transformation庫,擁有裁剪,著色,模糊,濾鏡等多種轉(zhuǎn)換效果,贊的不行不行的~~
2.GlidePalette(https://github.com/florent37/GlidePalette)
一個可以在Glide加載時很方便使用Palette的庫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,520評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,362評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,805評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,541評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,896評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,062評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,608評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,356評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,555評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,769評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,175評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,489評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,289評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,516評論 2 379

推薦閱讀更多精彩內(nèi)容