安卓專案實戰之:幫你從Glide3過渡到Glide4的完美攻略
Glide4:Glide3的優化版
相比於Glide 3 而言,Glide4並不能算是有什麼突破性的升級,而更多的是一些API工整方面的優化,相比於Glide3的API,Glide4進行了更加科學合理的調整,使得易讀性,易寫性,可擴充套件性等方面都有了不錯的提升,但如果你已經對Glide3非常熟悉的話,並不是就必須要切換到Glide4上面來,因為Glide4能實現的功能Glide3也能實現,而且Glide4在效能方面也並沒有什麼提升,但是對於剛接觸Glide的朋友而言,直接上手Glide4是最佳選擇。
當然對於已經熟練掌握Glide3用法的朋友,如果想遷移到Glide4上來也是一件很容易的事,因為改動雖然有,但是並不大,而且改的也僅僅是表象,底層實現基本沒變,只要看完本篇即可成功完成過渡。
本文重新排版,參考自部落格: https://blog.csdn.net/guolin_blog/article/details/78582548
新增依賴
dependencies {
compile 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}
新增依賴時如果報錯,嘗試解決如下,在Project的build.gradle檔案中新增倉庫:
allprojects {
repositories {
jcenter()
//需要新增的部分
maven { url "https://maven.google.com"}
}
}
在新增依賴時,相比於Glide 3,這裡多添加了一個compiler的庫,這個庫是用於生成Generated API的,有了它我們就可以完全使用Glide3的語法來書寫程式碼了,不同的是需要使用GlideApp去呼叫,具體用法見後文。
和Glide 3的相同點
Glide4 和Glide3一樣,核心程式碼就只有下面這一行:
Glide.with(this).load(url).into(imageView) ;
和Glide 3的不同點
1,RequestOptions物件的引入
在使用Glide3的時候我們知道,可以設定圖片載入的預設佔位圖,異常佔位圖,以及指定載入的圖片寬高,指定快取策略,設定圖片變換等,在Glide3中我們的寫法是這樣的:
Glide.with(this)
.load(url)
.placeholder(R.drawable.loading) // 佔位圖
.error(R.drawable.error) // 異常佔位圖
.skipMemoryCache(true) // true表示禁用記憶體快取
.diskCacheStrategy(DiskCacheStrategy.NONE) // 禁用磁碟快取
.override(Target.SIZE_ORIGINAL) // 指定載入圖片的原始尺寸
// .transforms(...);
.circleCrop() // 圖片變換功能:使用內建的圓角變換效果,本質也是呼叫了.transforms(...)方法,如果要自定義變換就必須實現.transforms(...)去指定了,或使用圖片變換開源庫glide-transformations
.into(imageView);
可以發現在Glide 3當中,像placeholder()、error()、diskCacheStrategy()等等一系列的API,都是直接串聯在Glide三步走方法中使用的。
而在Glide 4中引入了一個RequestOptions物件,將這一系列的API都移動到了RequestOptions當中,使用如下:
RequestOptions options = new RequestOptions()
.placeholder(R.drawable.ic_launcher_background)
.error(R.drawable.error)
.diskCacheStrategy(DiskCacheStrategy.NONE);
Glide.with(this)
.load(url)
.apply(options)
.into(imageView);
Glide4的使用只要在Glide的三步走之間加入一個apply()方法,來應用我們剛才建立的RequestOptions物件即可。
Glide 4這樣做的好處是可以使我們擺脫冗長的Glide載入語句,而且還能進行自己的API封裝,比如你就可以寫出這樣的Glide載入工具類:
public class GlideUtil {
public static void load(Context context, String url, ImageView imageView, RequestOptions options) {
Glide.with(context)
.load(url)
.apply(options)
.into(imageView);
}
}
2,指定圖片載入的格式(注意Glide4新版本中asBitmap呼叫的位置改動)
一般情況下我們使用核心程式碼載入圖片時,不管我們傳入的是一張普通圖片,還是一張GIF圖片,Glide都會自動進行判斷,並且可以正確地把它解析並展示出來。
指定載入的圖片格式是靜態圖片,不需要Glide幫我們判斷圖片格式:
Glide.with(this)
.asBitmap()
.load("http://guolin.tech/test.gif")
.into(imageView);
這樣指定之後,如果傳入的是GIF圖片,那麼只會顯示第一幀。
此外注意:在Glide 3中的語法是先load()再asBitmap()的,而在Glide 4中是先asBitmap()再load()的。
類似地,既然我們能強制指定載入靜態圖片,就也能強制指定載入動態圖片,對應的方法是asGif()。而Glide 4中又新增了asFile()方法和asDrawable()方法,分別用於強制指定檔案格式的載入和Drawable格式的載入,用法都比較簡單,就不再進行演示了。
3,回撥與監聽的寫法和Glide3基本一致
例如下面簡單的示例,更多的用法可參考:安卓專案實戰之Glide高手養成(三):Glide的回撥與監聽
SimpleTarget<Drawable> simpleTarget = new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
imageView.setImageDrawable(resource);
}
};
public void loadImage(View view) {
Glide.with(this)
.load("http://guolin.tech/book.png")
.into(simpleTarget);
}
自定義模組
自定義模組功能可以將更改Glide配置,替換Glide元件等操作獨立出來,使得我們能輕鬆地對Glide的各種配置進行自定義,並且又和Glide的圖片載入邏輯沒有任何交集,這也是一種低耦合程式設計方式的體現。下面我們就來學習一下自定義模組要如何實現。
首先定義一個我們自己的模組類,並讓它繼承自AppGlideModule,如下所示:
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
// 用來更改Glide配置時使用
@Override
public void applyOptions(Context context, GlideBuilder builder) {
}
// 用於替換Glide元件時使用
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
}
}
可以看到,在MyAppGlideModule類當中,我們重寫了applyOptions()和registerComponents()方法,這兩個方法分別就是用來更改Glide配置以及替換Glide元件的。
注意在MyAppGlideModule類在上面,我們加入了一個@GlideModule的註解,這是Gilde 4和Glide 3最大的一個不同之處。在Glide 3中,我們定義了自定義模組之後,還必須在AndroidManifest.xml檔案中去註冊它才能生效,而在Glide 4中是不需要的,因為@GlideModule這個註解已經能夠讓Glide識別到這個自定義模組了。
這樣的話,我們就將Glide自定義模組的功能完成了。後面只需要在applyOptions()和registerComponents()這兩個方法中加入具體的邏輯,就能實現更改Glide配置或者替換Glide元件的功能了。詳情還是請參考 Android圖片載入框架最全解析(六),探究Glide的自定義模組功能 這篇文章,這裡就不再展開討論了。
支援延續Glide3一模一樣的用法:使用Generated API
Generated API是Glide 4中全新引入的一個功能,它的工作原理是使用註解處理器 (Annotation Processor) 來生成出一個API,在Application模組中可使用該流式API一次性呼叫到RequestBuilder,RequestOptions和整合庫中所有的選項。
簡單點說就是Glide 4仍然給我們提供了一套和Glide 3一模一樣的流式API介面。畢竟有些人還是覺得Glide 3的API更好用一些,比如說我。
Generated API對於熟悉Glide 3的朋友來說那是再簡單不過了,基本上就是和Glide 3一模一樣的用法,只不過需要把Glide關鍵字替換成GlideApp關鍵字,如下所示:
GlideApp.with(this)
.load(url)
.placeholder(R.drawable.loading)
.error(R.drawable.error)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(Target.SIZE_ORIGINAL)
.circleCrop()
.into(imageView);
上面的程式碼和我們文章開始在Glide3中使用的程式碼除了變成了使用GlideApp呼叫外其他的完全一致。
但是我們需要先通過操作生成GlideApp這個類:
GlideApp這個類是通過編譯時註解自動生成的,首先確保你的程式碼中有一個自定義的模組,並且給它加上了@GlideModule註解,也就是我們在上一節所講的內容。然後在Android Studio中點選選單欄Build -> Rebuild Project,GlideApp這個類就會自動生成了。
當然,Generated API所能做到的並不只是這些而已,它還可以對現有的API進行擴充套件,定製出任何屬於你自己的API。
下面我來具體舉個例子,比如說我們要求專案中所有圖片的快取策略全部都要快取原始圖片,那麼每次在使用Glide載入圖片的時候,都去指定diskCacheStrategy(DiskCacheStrategy.DATA)這麼長長的一串程式碼,確實是讓人比較心煩。這種情況我們就可以去定製一個自己的API了。
定製自己的API需要藉助@GlideExtension和@GlideOption這兩個註解。建立一個我們自定義的擴充套件類,程式碼如下所示:
@GlideExtension
public class MyGlideExtension {
private MyGlideExtension() {
}
@GlideOption
public static void cacheSource(RequestOptions options) {
options.diskCacheStrategy(DiskCacheStrategy.DATA);
}
}
這裡我們定義了一個MyGlideExtension類,並且給加上了一個@GlideExtension註解,然後要將這個類的建構函式宣告成private,這都是必須要求的寫法。
接下來就可以開始自定義API了,這裡我們定義了一個cacheSource()方法,表示只快取原始圖片,並給這個方法加上了@GlideOption註解。注意自定義API的方法都必須是靜態方法,而且第一個引數必須是RequestOptions,後面你可以加入任意多個你想自定義的引數。
在cacheSource()方法中,我們仍然還是呼叫的diskCacheStrategy(DiskCacheStrategy.DATA)方法,所以說cacheSource()就是一層簡化API的封裝而已。
然後在Android Studio中點選選單欄Build -> Rebuild Project,神奇的事情就會發生了,你會發現你已經可以使用這樣的語句來載入圖片了:
GlideApp.with(this)
.load(url)
.cacheSource()
.into(imageView);
有了這個強大的功能之後,我們使用Glide就能變得更加靈活了。
解鎖Glide 4在專案裡面使用的新姿勢
1,首先當然是新增依賴了,省略…
2,然後我們自定義一個CusGlideApp,來繼承AppGlideModule,寫法如下:
@GlideModule
public final class CusGlideApp extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
super.applyOptions(context, builder);
}
}
注意:別忘記要新增@GlideModule註解。
3,然後在Android Studio中點選選單欄Build -> Rebuild Project,GlideApp這個類就會自動生成了。
4,定義Glide使用的工具類GlideUtil,程式碼如下:
public class GlideUtil {
public static void loadImage(Context context, Object imgUrl, SimpleTarget<Drawable> target) {
GlideApp.with(context)
.load(imgUrl)
.placeholder(R.drawable.img_viewer_placeholder)
.error(R.drawable.img_viewer_placeholder)
.into(target);
}
public static void loadImage(Context context, Object imgUrl, ImageView imageView) {
GlideApp.with(context)
.load(imgUrl)
.placeholder(R.drawable.img_viewer_placeholder)
.error(R.drawable.img_viewer_placeholder)
.into(imageView);
}
// 注意和上面的區別,一個是Glide3寫法(需配合GlideApp使用)一個是Glide4寫法
public static void load(Context context, String url, ImageView imageView, RequestOptions options) {
Glide.with(context)
.load(url)
.apply(options)
.into(imageView);
}
}
這樣GlideUtil的工具類就建立完成了,以後載入圖片就只要呼叫一個方法就ok了。
之前Glide3系列文章提到的所有的內容均適用於Glide4,只是在呼叫語法規則和書寫格式上有略微的區別而已,更多使用請參考Glide系列文章