Android 圖片加載(四)Glide自定義模塊

Glide內(nèi)部HTTP通訊組件的底層實現(xiàn)是基于HttpUrlConnection來進(jìn)行定制的。但是HttpUrlConnection的可擴展性比較有限盐股,因此我們今天介紹如何將Glide中的HTTP通訊組件替換成OkHttp。

一欲侮、前言

Glide v3中攒驰,當(dāng)我們創(chuàng)建好一個自定義模塊之后,還必須在AndroidManifest.xml文件中注冊它才能生效茬斧。隨著Glide框架的不斷優(yōu)化腰懂,在Glide v4中我們只需要使用@GlideModule這個注解就能夠讓Glide輕輕松松識別到我們創(chuàng)建的自定義模塊。

Glide已經(jīng)更新到4.9.0项秉,本文就不去介紹Glide v3中的自定義模塊绣溜,只介紹Glide v4中如何自定義模塊。當(dāng)然如果感興趣的話也可以學(xué)習(xí)一下舊版本中的自定義模塊娄蔼,推薦一篇非常優(yōu)秀的文章怖喻。

二、自定義模塊基本使用

Glide v4是使用注解機制來完成自定義模塊的創(chuàng)建工作的岁诉,因此在工作正式開始之前我們還需要引入一些必需的依賴庫锚沸。

1、添加對 Glide 的注解解析器的依賴和對OkHttp集成庫的依賴

implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.8.0'

2涕癣、創(chuàng)建自定義模塊

從Glide v4開始哗蜈,Glide框架引入了注解機制,自定義模塊的創(chuàng)建也變得非常簡單。

  1. 首先要實現(xiàn)AppGlideModule 類恬叹。
  2. 接著給上述實現(xiàn)添加@GlideModule注解候生。
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
        
    }

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        
    }
}
  1. 最后,你應(yīng)該在你的 proguard.cfg 中 keep 住你的 AppGlideModule 實現(xiàn)绽昼。
-keep public class  extends com.bumptech.glide.module.AppGlideModule
-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl

這樣模塊類就創(chuàng)建完成了唯鸭。我們可以看到上述代碼中有兩個需要重寫的方法applyOptions和registerComponents,那么這兩個方法的作用是什么呢硅确?

applyOptions

認(rèn)真閱讀過上一篇文章的同學(xué)對applyOptions()這個方法應(yīng)該比較熟悉了目溉,它在應(yīng)用程序選項一節(jié)中多次出現(xiàn)過,它的主要職責(zé)就是配置對大部分應(yīng)用程序合理的默認(rèn)選項菱农。

假如有這樣一個場景:我希望Glide在加載圖片的時候禁止任何緩存操作缭付。為了滿足這個條件,那么我應(yīng)用中的圖片加載語句可能是類似下面這樣的:

Glide.with(this)
        .asDrawable()
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .load(IMAGE_URL)
        .into(imageView);

一直重復(fù)編寫這么長的語句顯然是不理智的循未,此時我們就可以在applyOptions方法中配置所有請求的默認(rèn)選項:

@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
    RequestOptions requestOptions = new RequestOptions()
            .skipMemoryCache(true) //不使用內(nèi)存緩存
            .diskCacheStrategy(DiskCacheStrategy.NONE);  //原圖和縮略圖都不進(jìn)行磁盤緩存
    builder.setDefaultRequestOptions(requestOptions);
}

這樣所有的圖片加載請求在默認(rèn)情況下就不會進(jìn)行緩存操作了陷猫,我們的圖片加載語句也會變得很簡單:

Glide.with(this)
        .load(IMAGE_URL)
        .into(imageView);
registerComponents

registerComponents,顧名思義的妖,這個方法的作用就是注冊組件绣檬,這也是這一篇文章要介紹的重點內(nèi)容。

假如有一天產(chǎn)品經(jīng)理提出了一個新功能嫂粟,需要顯示圖片的加載進(jìn)度娇未,由于Glide內(nèi)部是基于HttpUrlConnection實現(xiàn)網(wǎng)絡(luò)通訊的,我們在它的基礎(chǔ)之上無法實現(xiàn)監(jiān)聽下載進(jìn)度的功能星虹,因此我們就需要用OkHttp替換HttpUrlConnection零抬。

@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addInterceptor(new ProgressInterceptor());  //攔截器
    OkHttpClient okHttpClient = builder.build();
    registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
}

這樣我們就成功地用OkHttp替換掉HttpUrlConnection來進(jìn)行網(wǎng)絡(luò)通訊。

Registry類中不僅定義了replace()方法宽涌,還有prepend()append()方法平夜,它們可以用于設(shè)置 Glide 嘗試每個ModelLoaderResourceDecoder之間的順序,我們可以根據(jù)實際需求選用卸亮。

假如你的 ModelLoader 或者 ResourceDecoder 在某個地方失敗了褥芒,這時候你想將已有的數(shù)據(jù)交由 Glide 的默認(rèn)行為來處理,可以使用 prepend()嫡良。 prepend() 將確保你的 ModelLoaderResourceDecoder 先于之前注冊的其他組件并被首先執(zhí)行锰扶。如果你的 ModelLoader 或者 ResourceDecoder 從其 handles() 方法中返回了一個 false 或失敗,所有其他的 ModelLoaderResourceDecoder 將以它們被注冊的順序執(zhí)行寝受,一次一個坷牛,作為一種回退方案。

要處理新的數(shù)據(jù)類型或提供一個到 Glide 默認(rèn)行為的回退很澄,使用 append()京闰。append() 將確保你的 ModelLoaderResourceDecoder 僅在 Glide 的默認(rèn)組件被嘗試后才會被調(diào)用颜及。 如果你正在嘗試處理 Glide 的默認(rèn)組件能處理的某些子類型 (例如一些特定的 Uri 授權(quán)或子類型),你可能需要使用 prepend() 來確保 Glide 的默認(rèn)組件不會在你的定制組件之前加載蹂楣。

要完全替換 Glide 的默認(rèn)行為并確保它絕不運行俏站,請使用 replace()replace() 將移除所有處理給定模型和數(shù)據(jù)類的 ModelLoaders痊土,并添加你的 ModelLoader 來代替肄扎。 replace() 在使用庫(例如 OkHttp 或 Volley)替換掉 Glide 的網(wǎng)絡(luò)邏輯時尤其有用,這種時候你會希望確保僅 OkHttp 或 Volley 被調(diào)用赁酝。


參考鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市酌呆,隨后出現(xiàn)的幾起案子衡载,更是在濱河造成了極大的恐慌,老刑警劉巖隙袁,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痰娱,死亡現(xiàn)場離奇詭異,居然都是意外死亡菩收,警方通過查閱死者的電腦和手機梨睁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坛梁,“玉大人而姐,你說我怎么就攤上這事腊凶』溃” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵钧萍,是天一觀的道長褐缠。 經(jīng)常有香客問我,道長风瘦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任万搔,我火速辦了婚禮胡桨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞬雹。我一直安慰自己昧谊,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布酗捌。 她就那樣靜靜地躺著呢诬,像睡著了一般涌哲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上尚镰,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天阀圾,我揣著相機與錄音,去河邊找鬼狗唉。 笑死初烘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的敞曹。 我是一名探鬼主播账月,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼澳迫!你這毒婦竟也來了局齿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤橄登,失蹤者是張志新(化名)和其女友劉穎抓歼,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拢锹,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡谣妻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了卒稳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹋半。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖充坑,靈堂內(nèi)的尸體忽然破棺而出减江,到底是詐尸還是另有隱情,我是刑警寧澤捻爷,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布辈灼,位于F島的核電站,受9級特大地震影響也榄,放射性物質(zhì)發(fā)生泄漏巡莹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一甜紫、第九天 我趴在偏房一處隱蔽的房頂上張望降宅。 院中可真熱鬧,春花似錦囚霸、人聲如沸腰根。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唠雕。三九已至贸营,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岩睁,已是汗流浹背钞脂。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捕儒,地道東北人冰啃。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像刘莹,于是被迫代替她去往敵國和親阎毅。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

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