1. 程式人生 > >Glide 4.0.0 RC0 使用詳解

Glide 4.0.0 RC0 使用詳解

Glide 4.0.0 RC0 官方說明

1.變化

單獨列出的更改太多,但這裡有一些亮點:

  • 新的文件,使用者可以通過提交請求到Glide’s gh-pages分支貢獻。
  • 使用者可以新增新型別或自定義選項集來輕鬆地自定義Glide流暢的API。
  • 大量簡化個人請求型別,確保選項始終如一,易於使用,即使您正在載入不同型別的資源。
  • 各種效能改進,包括在下載取樣影象時大量減少垃圾,更加智慧的預設磁碟快取策略,以及載入GIF時效能提升。
  • 改進了檢視大小和佈局的處理,特別是在RecyclerView中。

2.狀態

Glide 4.0由Google的各種團隊內部使用,4.0被認為是內部穩定的。但外部使用者可能會發現內部尚未發現的問題。因此,將此作為RC釋出。如果沒有發現穩定性或API中的重大問題,預計不久之後就會發布非RC版本。

3.釋出時間表

Glide在過去採取了一種相當隨意的方式釋出,主要是因為在空閒的時候採取做。未來,Glide有望嘗試提供定期釋出:

  • 每個月15日左右發行(確切的日期可能有所不同)
  • 只有在前版本中沒有更改的情況下才會跳過此版本。
  • 只有在主要版本升級的時候才會去更改API。

4.下載

從V3遷移到V4

1.Options(選項)

一個在GlideV4變化較大的是庫處理選項的方式(centerCrop(),placeholder()等)。在Glide v3中,選項是由一系列複雜的多型別構建器單獨處理的。在Glide v4中,這些已被具有單一型別的單個構建器和可以提供給構建器的一系列選項的物件所替代。Glide 生成的API通過將選項物件和任何包含的整合庫與構建器的選項合併,來建立單個流暢的API。
如下,options分類被放在不同的物件裡,我們挨著看每個具體的方法:

(1)RequestBuilder

包括以下方法:

listener()
thumbnail()
load()
into()

在Glide v4中,只有一個RequestBuilder,它使用單一的型別載入到你的專案(型別Bitmap,Drawable,GifDrawable等)。RequestBuilder提供了影響載入過程本身的選項,比如要載入的型別(url, uri etc),任何 thumbnail()和listener()請求,RequestBuilder也提供在哪裡開始載入的方法, into() or preload()。
我們看一下,下面的示例程式碼:

RequestBuilder<Drawable> requestBuilder = Glide.with(fragment)
    .load(url);

requestBuilder
    .thumbnail(Glide.with(fragment)
        .load(thumbnailUrl))
    .listener(requestListener)
    .load(url)
    .into(imageView);

實戰示例:

Glide.with(this)
      .load(ImageConfig.URL_WEBP)
      .thumbnail(Glide.with(this).load(ImageConfig.URL_JPEG))
      .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        Logger.e("onLoadFailed --->" +e);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        Logger.e("onResourceReady---> " + resource);
                        return false;
                    }
                })
     .into(iv_test1);

效果圖:
我們可以看到第一次安裝完成之後,在gif沒有加載出來先載入縮圖,然後再載入gif圖片,個人感覺載入gif圖片的速度是比之前快多了,這些都是載入網路圖片和網速也有一定關係。
載入完成後,推出APP,再次進入會首先載入之前快取在本地的圖片,所以還是那麼的爽。

這裡寫圖片描述

(2)RequestOptions

包括以下方法:

centerCrop()
placeholder()
error()
priority()
diskCacheStrategy()

大多數的設定已經放到了RequestOptions物件中:
示例:

RequestOptions options = new RequestOptions()
    .centerCrop()
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .priority(Priority.HIGH)
    .diskCacheStrategy(DiskCacheStrategy.NONE);

RequestOptions一次設定之後,可以在多處使用

RequestOptions myOptions = new RequestOptions()
    .fitCenter()
    .override(100, 100);

Glide.with(fragment)
    .load(url)
    .apply(myOptions)
    .into(drawableView);

Glide.with(fragment)
    .asBitmap()
    .apply(myOptions)
    .load(url)
    .into(bitmapView);

實戰例項:

RequestOptions options = new RequestOptions()
        .centerCrop()
        .placeholder(R.mipmap.ic_launcher_round)
        .error(R.mipmap.ic_launcher)
        .priority(Priority.HIGH)
        .diskCacheStrategy(DiskCacheStrategy.NONE);

Glide.with(this)
        .load(ImageConfig.URL_GIF)
        .apply(options)
        .thumbnail(Glide.with(this)
                      .load(ImageConfig.URL_JPEG))
        .into(iv_test1);

Glide.with(this)
        .load(ImageConfig.URL_WEBP)
        .apply(options)
        .thumbnail(Glide.with(this)
                .load(ImageConfig.URL_JPEG))
        .into(iv_test2);

效果圖:
這裡寫圖片描述

(3)TransitionOptions

顧名思義,變換相關的設定在這裡:

包括以下方法:

crossFade()
animate()

選擇一個你所需要的TransitionOptions:

示例:

Glide.with(fragment)
    .load(url)
    .transition(withCrossFade(R.anim.fade_in, 300));

實戰示例:

//使用變換效果
Glide.with(this)
        .load(ImageConfig.URL_WEBP)
        .apply(options)
        .transition(new DrawableTransitionOptions().crossFade(2000))
        .thumbnail(Glide.with(this)
                .load(ImageConfig.URL_JPEG))
        .into(iv_test1);

//不使用變換效果
Glide.with(this)
        .load(ImageConfig.URL_WEBP)
        .apply(options)
        .transition(new DrawableTransitionOptions().dontTransition())
        .thumbnail(Glide.with(this)
                .load(ImageConfig.URL_JPEG))
        .into(iv_test2);

效果圖:
這裡寫圖片描述

(4)生成的API

關於

GlideV4:使用一個註釋處理器生成了一個API,允許應用程式訪問的所有選項RequestBuilder,RequestOptions以及任何包含整合庫在一個流暢的API。

生成的API有兩個目的:

  • 整合庫可以通過自定義選項擴充套件Glide的API。
  • 應用程式可以通過新增捆綁常用選項的方法來擴充套件Glide的API。

儘管這兩個任務都可以通過編寫RequestOptions的自定義子類來手工完成,但是這樣做是具有挑戰性的,並且會產生一個不那麼流暢的API。

入門

要觸發API生成,請在應用程式中包含一個AppGlideModule實現:

package com.example.myapp;

import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

請注意,AppGlideModule實現必須始終註釋@GlideModule。如果註釋不存在,則不會發現該模組,並且您將在日誌中看到一條帶有Glide日誌標記的警告,該日誌標記指示該模組無法找到。

API在與應用程式AppGlideModule提供的實現相同的包中生成,並且GlideApp預設命名。應用程式可以通過啟動所有,載入GlideApp.with()而不是使用API Glide.with()

GlideApp.with(fragment)
   .placeholder(R.drawable.placeholder)
   .fitCenter()
   .load(myUrl)
   .into(imageView);

請注意,與Glide.with()類似的選項fitCenter(),並placeholder()提供直接的建設者,並不需要傳遞作為一個獨立的RequestOptions物件。

實戰演示

建立自定義GlideModle:
這裡寫圖片描述

⚠️ 有的童鞋發現@GlideModule之後並沒有生成GlideAPP物件,這時候需要注意兩步:

1、依賴是否都匯入
compile 'com.github.bumptech.glide:glide:4.0.0-RC0'
compile 'com.github.bumptech.glide:compiler:4.0.0-RC0'
compile 'com.android.support:support-v4:25.3.1'

2、點選“Make Project”

這時候會發現自定義的AppGlideModle被注入到GeneratedAppGlideModuleImpl裡面,如圖:
這裡寫圖片描述

這時候已經可以去使用GlideApp.with(this),接下來就會讓我們回到熟悉的感覺:

GlideApp.with(this)
        .load(ImageConfig.URL_WEBP)
        .sizeMultiplier(0.5f)
        .centerCrop()
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .error(R.mipmap.ic_launcher)
        .into(iv_test1);

是不是有種找回了記憶中的味道!!!

2.Types and Targets (型別和目標)

(1)載入的資源型別

Glide允許您指定要載入的資源型別。如果指定超型別,則Glide將嘗試載入任何可用的子型別。例如,如果您要求Drawable,Glide可能會載入BitmapDrawable或GifDrawable。如果您要求GifDrawable,如果影象不是GIF,Glide將載入GifDrawable或錯誤(即使它恰好是完全有效的影象)。

預設情況下請求可繪製值:

Glide.with(fragment).load(url)

要求點陣圖:

Glide.with(fragment).asBitmap()

獲取檔案路徑(最適合本地映像):

Glide.with(fragment).asFile()

要將遠端檔案下載到快取中並獲取檔案路徑:

Glide.with(fragment).downloadOnly()
// or if you have the url already:
Glide.with(fragmetn).download(url);

(2)Drawables

GlideDrawable在Glide v3已被刪改為Android Drawable。GlideBitmapDrawable已被刪改為BitmapDrawable。

如果你想知道一個Drawable是否是動畫的,你可以檢查它是否是一個例項Animatable

boolean isAnimated = drawable instanceof Animatable

(3)Targets

onResourceReady的回撥已經發生了改變,例如Drawables:

以前:

onResourceReady(GlideDrawable drawable, GlideAnimation<? super GlideDrawable> anim) 

現在:

onResourceReady(Drawable drawable, Transition<? super Drawable> transition);

同樣onLoadFailed也改變了:

以前:

onLoadFailed(Exception e, Drawable errorDrawable)

現在:

onLoadFailed(Drawable errorDrawable)

3.Configuration(配置)

在Glide v3中,可以配置一個活著多個GlideModules。在Glide v4中,通過類似但稍微更復雜的系統進行配置。

(1)Applications(應用)

在Glide v3中,你可得GlideModule可能是這樣的:

public class GiphyGlideModule implements GlideModule {
  @Override
  public void applyOptions(Context context, GlideBuilder builder) {
    builder.setMemoryCache(new LruResourceCache(10 * 1024 * 1024));
  }

  @Override
  public void registerComponents(Context context, Registry registry) {
    registry.append(Api.GifResult.class, InputStream.class, new GiphyModelLoader.Factory());
  }
}

在Glide v4中,您可以將其轉換成AppGlideModule如下所示:

@GlideModule
public class GiphyGlideModule extends AppGlideModule {
  @Override
  public void applyOptions(Context context, GlideBuilder builder) {
    builder.setMemoryCache(new LruResourceCache(10 * 1024 * 1024));
  }

  @Override
  public void registerComponents(Context context, Registry registry) {
    registry.append(Api.GifResult.class, InputStream.class, new GiphyModelLoader.Factory());
  }
}

⚠️注意: Glide4.0 必須要使用註解: `@GlideModule

您的應用程式有多個GlideModules,將其中一個轉換為AppGlideModule,其他的轉換為LibraryGlideModules。除非出現一個AppGlideModule,否則不會發現LibraryGlideModules,因此您不能只使用LibraryGlideModules。`

(2)Libraries

有一個或多個GlideModules的庫應該使用LibraryGlideModule而不是AppGlideModule。庫不應該使用AppGlideModules,因為每個應用程式只能有一個,所以在一個庫中包含它不僅會阻止庫的使用者設定他們自己的選項,而且如果多個庫包含一個AppGlideModule,它也會導致衝突。

例如, the Volley GlideModule 在 V3:

public class VolleyGlideModule implements GlideModule {
  @Override
  public void applyOptions(Context context, GlideBuilder builder) {
    // Do nothing.
  }

  @Override
  public void registerComponents(Context context, Registry registry) {
    registry.replace(GlideUrl.class, InputStream.class, new VolleyUrlLoader.Factory(context));
  }
}

在V4中轉換成如下:

@GlideModule
public class VolleyLibraryGlideModule extends LibraryGlideModule {
  @Override
  public void registerComponents(Context context, Registry registry) {
    registry.replace(GlideUrl.class, InputStream.class, new VolleyUrlLoader.Factory(context));
  }
}

(3)Manifest parsing

為了簡化遷移,清單解析和舊GlideModule介面已被棄用,但在v4中仍然支援。AppGlideModules,LibraryGlideModules和被棄用GlideModule的都可以在應用程式中共存。

但是,為了避免檢查元資料(和相關的錯誤)的效能開銷,您可以在遷移完成後通過覆蓋以下方法來禁用清單解析AppGlideModule:

@GlideModule
public class GiphyGlideModule extends AppGlideModule {
  @Override
  public boolean isManifestParsingEnabled() {
    return false;
  }

  ...
}

接下來可以看看原始碼解析,有個更深入理解:

掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~

公眾號回覆“資料獲取”,獲取更多幹貨哦~