1. 程式人生 > >安卓專案實戰之:幫你從Glide3過渡到Glide4的完美攻略

安卓專案實戰之:幫你從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系列文章