一、簡介
Glide v4 使用注解處理器 (Annotation Processor) 來生成出一個(gè) API,在 Application 模塊中可使用該流式 API 一次性調(diào)用到 RequestBuilder, RequestOptions 和集成庫中所有的選項(xiàng)。
Generated API 模式的設(shè)計(jì)出于以下兩個(gè)目的:
集成庫可以為 Generated API 擴(kuò)展自定義選項(xiàng)。
在 Application 模塊中可將常用的選項(xiàng)組打包成一個(gè)選項(xiàng)在 Generated API 中使用
雖然以上所說的工作均可以通過手動(dòng)創(chuàng)建 RequestOptions 子類的方式來完成,但想將它用好更具有挑戰(zhàn),并且降低了 API 使用的流暢性。
二、開始使用
2.1 有效使用范圍
Generated API 目前僅可以在 Application 模塊內(nèi)使用。這一限制可以讓我們僅持有一份 Generated API,而不是各個(gè) Library 和 Application 中均有自己定義出來的 Generated API。這一做法會(huì)讓 Generated API 的調(diào)用更簡單,并確保 Application 模塊中 Generated API 調(diào)用的選項(xiàng)在各處行為一致。這一限制在接下來的版本中也許會(huì)被取消(以實(shí)驗(yàn)性或其他的方式給出)。
2.2 Java
要在 Application 模塊中使用 Generated API,你需要執(zhí)行以下兩步:
2.2.1 添加 Glide 注解處理器的依賴:
repositories {
mavenCentral()
}
dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
}
2.2.2 在 Application 模塊中包含一個(gè) AppGlideModule 的實(shí)現(xiàn):
package com.example.myapp;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}
你不必去重寫 AppGlideModule 中的任何一個(gè)方法。子類中完全可以不用寫任何東西,它只需要繼承 AppGlideModule 并且添加 @GlideModule 注解。
AppGlideModule 的實(shí)現(xiàn)必須使用 @GlideModule 注解標(biāo)記。如果注解不存在,該 module 將不會(huì)被 Glide 發(fā)現(xiàn),并且在日志中收到一條帶有 Glide tag 的警告,表示 module 未找到。
注意: 程序庫 (Library) 不應(yīng)該包含 AppGlideModule 實(shí)現(xiàn),詳見配置。
2.3 Kotlin
如果你正在使用 Kotlin,你可以選擇:
- 使用 Java 按前面所述實(shí)現(xiàn)所有的 Glide 注解類(
AppGlideModule,LibraryGlideModule,以及GlideExtension)。
使用 Kotlin 實(shí)現(xiàn)注解類,但需要添加一個(gè) kapt 依賴以替換 Glide 的 annotationProcessor 依賴:
dependencies {
kapt 'com.github.bumptech.glide:compiler:4.8.0'
}
注意,你還需要在你的 build.gradle 文件中包含 kotlin-kapt 插件:
apply plugin: 'kotlin-kapt'
此外,如果你有其他的注解處理器,它們都必須全部被從 annotationProcessor 轉(zhuǎn)換為 kapt:
dependencies {
kapt "android.arch.lifecycle:compiler:1.0.0"
kapt 'com.github.bumptech.glide:compiler:4.8.0'
}
關(guān)于 kapt 的使用,請查看官方文檔。
2.4 Android Studio
Android Studio 在大多數(shù)時(shí)候都可以正確地處理注解處理器 (annotation processor) 和 generated API。然而,當(dāng)你第一次添加你的 AppGlideModule 或做了某些類型的修改后,你可能需要重新構(gòu)建 (rebuild) 你的項(xiàng)目。 無論何時(shí),如果你發(fā)現(xiàn) API 沒有被 import,或看起來已經(jīng)過期,你可以通過以下方法重新構(gòu)建:
打開
Build菜單;點(diǎn)擊
Rebuild Project。
三、使用 Generated API
Generated API 默認(rèn)名為 GlideApp,與 Application 模塊中 AppGlideModule 的子類包名相同。在 Application 模塊中將 Glide.with() 替換為 GlideApp.with(),即可使用該 API 去完成加載工作:
GlideApp.with(fragment)
.load(myUrl)
.placeholder(R.drawable.placeholder)
.fitCenter()
.into(imageView);
與 Glide.with() 不同,諸如 fitCenter() 和 placeholder() 等選項(xiàng)在 Builder 中直接可用,并不需要再傳入單獨(dú)的 RequestOptions 對象。
四、GlideExtension
Glide Generated API 可在 Application 和 Library 中被擴(kuò)展。擴(kuò)展使用被注解的靜態(tài)方法來添加新的選項(xiàng)、修改現(xiàn)有選項(xiàng)、甚至添加額外的類型支持。
@GlideExtension 注解用于標(biāo)識一個(gè)擴(kuò)展 Glide API 的類。任何擴(kuò)展 Glide API 的類都必須使用這個(gè)注解來標(biāo)記,否則其中被注解的方法就會(huì)被忽略。
被 @GlideExtension 注解的類應(yīng)以工具類的思維編寫。這種類應(yīng)該有一個(gè)私有的、空的構(gòu)造方法,應(yīng)為 final 類型,并且僅包含靜態(tài)方法。被注解的類可以含有靜態(tài)變量,可以引用其他的類或?qū)ο蟆?/p>
在 Application 模塊中可以根據(jù)需求實(shí)現(xiàn)任意多個(gè)被 @GlideExtension 注解的類,在 Library 模塊中同樣如此。當(dāng) AppGlideModule 被發(fā)現(xiàn)時(shí),所有有效的 Glide 擴(kuò)展類 會(huì)被合并,所有的選項(xiàng)在 API 中均可以被調(diào)用。合并沖突會(huì)導(dǎo)致 Glide 的 Annotation Processor 拋出編譯錯(cuò)誤。
被 @GlideExtention 注解的類有兩種擴(kuò)展方式:
GlideOption- 為RequestOptions添加一個(gè)自定義的選項(xiàng)。GlideType- 添加對新的資源類型的支持(GIF,SVG等等)。
4.1 GlideOption
用 @GlideOption 注解的靜態(tài)方法用于擴(kuò)展 RequestOptions 。GlideOption 可以:
定義一個(gè)在
Application模塊中頻繁使用的選項(xiàng)集合。創(chuàng)建新的選項(xiàng),通常與 Glide 的
Option類一起使用。
要定義一個(gè)選項(xiàng)集合,你可以這么寫:
@GlideExtension
public class MyAppExtension {
// Size of mini thumb in pixels.
private static final int MINI_THUMB_SIZE = 100;
private MyAppExtension() { } // utility class
@GlideOption
public static void miniThumb(RequestOptions options) {
options
.fitCenter()
.override(MINI_THUMB_SIZE);
}
這將會(huì)在 RequestOptions 的子類中生成一個(gè)方法,類似這樣:
public class GlideOptions extends RequestOptions {
public GlideOptions miniThumb() {
MyAppExtension.miniThumb(this);
}
...
}
你可以為方法任意添加參數(shù),但要保證第一個(gè)參數(shù)為 RequestOptions。
@GlideOption
public static void miniThumb(RequestOptions options, int size) {
options
.fitCenter()
.override(size);
}
在自動(dòng)生成的方法中新添的參數(shù)同樣被加了進(jìn)來:
public GlideOptions miniThumb(int size) {
MyAppExtension.miniThumb(this);
}
之后你就可以使用生成的 GlideApp 類調(diào)用你的自定義方法:
GlideApp.with(fragment)
.load(url)
.miniThumb(thumbnailSize)
.into(imageView);
使用 @GlideOption 標(biāo)記的方法應(yīng)該為靜態(tài)方法,并且返回值為空。請注意,這些生成的方法在一般的 Glide 和 RequestOptions 類里不可用。
4.2 GlideType
被 @GlideType 注解的靜態(tài)方法用于擴(kuò)展 RequestManager。被 @GlideType 注解的方法允許你添加對新的資源類型的支持,包括指定默認(rèn)選項(xiàng)。
例如,為添加對 GIF 的支持,你可以添加一個(gè)被 @GlideType 注解的方法:
@GlideExtension
public class MyAppExtension {
private static final RequestOptions DECODE_TYPE_GIF = decodeTypeOf(GifDrawable.class).lock();
@GlideType(GifDrawable.class)
public static void asGif(RequestBuilder<GifDrawable> requestBuilder) {
requestBuilder
.transition(new DrawableTransitionOptions())
.apply(DECODE_TYPE_GIF);
}
}
這樣會(huì)生成一個(gè)包含對應(yīng)方法的 RequestManager:
public class GlideRequests extends RequesetManager {
public RequestBuilder<GifDrawable> asGif() {
RequestBuilder<GifDrawable> builder = as(GifDrawable.class);
MyAppExtension.asGif(builder);
return builder;
}
...
}
之后你可以使用生成的 GlideApp 類調(diào)用你的自定義類型:
GlideApp.with(fragment)
.asGif()
.load(url)
.into(imageView);
被 @GlideType 標(biāo)記的方法必須使用 RequestBuilder<T> 作為其第一個(gè)參數(shù),這里的泛型 <T> 對應(yīng) @GlideType 注解中傳入的類。該方法應(yīng)為靜態(tài)方法,且返回值為空。方法必須定義在一個(gè)被 @GlideExtension 注解標(biāo)記的類中。