Google推薦——Glide使用詳解

零、前言

本文所使用的Glide版本爲3.7.0html

「推薦」設計模式系列

設計模式(零)- 面向對象的六大原則
設計模式(一)- 單例模式
設計模式(二)- Builder模式
設計模式(三)- 原型模式
設計模式(四)- 工廠模式
設計模式(五)- 策略模式
設計模式(六)- 狀態模式
設計模式(七)- 責任鏈模式
設計模式(八)- 解釋器模式
設計模式(九)- 命令模式
設計模式(十)- 觀察者模式
設計模式(十一)- 備忘錄模式
設計模式(十二)- 迭代器模式
持續更新中...android

1、簡介

Glide,一個被google所推薦的圖片加載庫,做者是bumptech。這個庫被普遍運用在google的開源項目中,包括2014年的google I/O大會上發佈的官方app。(PS:衆所周知的簡介就到此爲止了)git

Glide 對於 Android SDK 的最低要求是 API level 10github

Glide滑行的意思,能夠看出這個庫的主旨就在於讓圖片加載變的流暢。如今被普遍使用,固然仍是有不少開發者使用Square公司的picasso,也有兩個庫的對比canvas

原文連接:http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en設計模式

譯文連接:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0327/2650.html緩存

2、使用

(一)導入

在AndroidStudio上添加依賴很是簡單服務器

dependencies {  
    compile 'com.github.bumptech.glide:glide:3.7.0'  
    compile 'com.android.support:support-v4:23.2.1'  
}

Glide 也支持 Maven 項目形式:網絡

<dependency>
  <groupId>com.github.bumptech.glide</groupId>
  <artifactId>glide</artifactId>
  <version>3.7.0</version>
</dependency>
<dependency>
  <groupId>com.google.android</groupId>
  <artifactId>support-v4</artifactId>
  <version>r7</version>
</dependency>

若是是Eclipse使用去下載Glide的jar在項目中使用就能夠了,jar的連接https://github.com/bumptech/glide/releasesapp

(二)基礎使用

基本方法

Glide的一個完整的請求至少須要三個參數,代碼以下:

String url = "http://img1.dzwww.com:8080/tupian_pl/20150813/16/7858995348613407436.jpg";
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Glide.with(context)
    .load(url)
    .into(imageView);
  • with(Context context) - 須要上下文,這裏還可使用 Activity、FragmentActivity、android.support.v4.app.Fragment、android.app.Fragment 的對象。將 Activity/Fragment 對象做爲參數的好處是,圖片的加載會和 Activity/Fragment 的生命週期保持一致,例如:onPaused 時暫停加載,onResume 時又會自動從新加載。因此在傳參的時候建議使用 Activity/Fragment 對象,而不是 Context。
  • load(String url) - 這裏咱們所使用的一個字符串形式的網絡圖片的 URL,後面會講解 load() 的更多使用方式
  • into(ImageView imageView) - 你須要顯示圖片的目標 ImageView

佔位圖設置

偶爾出現圖片加載慢或者加載不出來的狀況是難以免的,因此爲了 UI 能好看一些,咱們會使用佔位圖。Glide 也爲咱們提供這種方法 placeHolder() 和 error()

String url = "http://img1.dzwww.com:8080/tupian_pl/20150813/16/7858995348613407436.jpg";
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Glide.with(context)
    .load(url)
    .placeholder(R.drawable.place_image)//圖片加載出來前,顯示的圖片
    .error(R.drawable.error_image)//圖片加載失敗後,顯示的圖片
    .into(imageView);

注:這裏須要注意一點,placeholder() 和 error() 的參數都是隻支持 int 和 Drawable 類型的參數,這種設計應該是考慮到使用本地圖片比網絡圖片更加合適作佔位圖。

縮略圖

Glide 的縮略圖功能在這裏不得不說,和佔位圖略有不一樣,佔位圖必須使用資源文件才行,而縮略圖是動態的佔位圖能夠從網絡中加載。縮略圖會在世紀請求加載完成或者處理完以後才顯示。在原始圖片到達以後,縮略圖不會取代原始圖片,只會被抹除。

Glide 爲縮略圖提供了2種不一樣的加載方式,比較簡單的方式是調用 thumbnail() 方法,參數是 float 類型,做爲其倍數大小。例如,你傳入 0.2f 做爲參數,Glide 將會顯示原始圖片的20%的大小,若是原圖是 1000x1000 的尺寸,那麼縮略圖將會是 200x200 的尺寸。爲縮略圖明顯比原圖小得多,因此咱們須要確保 ImageView 的 ScaleType 設置的正確。

Glide.with( context )
    .load( url )
    .thumbnail( 0.2f )
    .into( imageView );

注:應用於請求的設置也將應用於縮略圖。

使用 thumbnail() 方法來設置是簡單粗暴的,可是若是縮略圖須要經過網絡加載相同的全尺寸圖片,就不會很快的顯示了。因此 Glide 提供了另外一種防止去加載縮略圖,先看代碼

private void loadImageThumbnailRequest(){
    // setup Glide request without the into() method
    DrawableRequestBuilder<String> thumbnailRequest = Glide.with( context ).load( url );
    // pass the request as a a parameter to the thumbnail request
    Glide.with( context )
        .load( url )
        .thumbnail( thumbnailRequest )
        .into( imageView );
}

與第一種方式不一樣的是,這裏的第一個縮略圖請求是徹底獨立於第二個原始請求的。該縮略圖能夠是不一樣的資源圖片,同時也能夠對縮略圖作不一樣的轉換,等等...

動畫開關

動畫效果可讓圖片加載變得更加的平滑,crossFade() 方法強制開啓 Glide 默認的圖片淡出淡入動畫,當前版本3.7.0是默認開啓的。crossFade() 還有一個重載方法 crossFade(int duration)。能夠控制動畫的持續時間,單位ms。動畫默認的持續時間是300ms。既然能夠添加動畫,那確定就能夠設置沒有任何淡出淡入效果,調用 dontAnimate()

Glide.with(context)
    .load(url)
    .crossFade()//或者使用 dontAnimate() 關閉動畫
    .placeholder(R.drawable.place_image)
    .error(R.drawable.error_image)
    .into(imageView);

PS:Glide 是能夠自定義動畫效果的,這個在後面會講解

圖片大小與裁剪

在項目開發過程當中,指定圖片顯示大小長長可能用到,畢竟從服務器獲取的圖片不必定都是符合設計圖的標準的。咱們在這裏就可使用 override(width,height) 方法,在圖片顯示到 ImageView 以前,從新改變圖片大小。

Glide.with(context)
    .load(url)
    .override(width,height)//這裏的單位是px
    .into(imageView);

在設置圖片到 ImageView 的時候,爲了不圖片被擠壓失真,ImageView 自己提供了 ScaleType 屬性,這個屬性能夠控制圖片顯示時的方式,具體的屬性使用仍是去搜索吧!Glide 也提供了兩個相似的方法 CenterCrop() 和 FitCenter(),CenterCrop() 方法是將圖片按比例縮放到足矣填充 ImageView 的尺寸,可是圖片可能會顯示不完整;而 FitCenter() 則是圖片縮放到小於等於 ImageView 的尺寸,這樣圖片是顯示完整了,可是 ImageView 就可能不會填滿了。

注:其實 Glide 的 CenterCrop() 和 FitCenter() 這兩個方法分別對應 ImageView 的 ScaleType 屬性中的 CENTER_CROP 和 FIT_CENTER 命名基本一致。

圖片的緩存處理

爲了更快的加載圖片,咱們確定但願能夠直接拿到圖片,而不是進行網絡請求,因此咱們須要緩存。Glide 經過使用默認的內存和磁盤緩存來避免沒必要要的網絡請求,以後咱們再詳細的去看它的實現。

內存緩存

內存緩存是 Glide 默認幫咱們作了的,除非你不須要,能夠調用 skipMemoryCache(true) 告訴 Glide 跳過內存緩存。這樣 Glide 就不會把這張圖片放到內存緩存中,該方法隻影響內存緩存。(不要問調用skipMemoryCache(false)的問題,Glide 是默認將圖片放入內存緩存中的)

磁盤緩存

磁盤緩存也是默認開啓的,固然也是能夠關閉的,不過關閉的方式略微有點不同。

Glide.with(context)
    .load(url)
    .skipMemoryCache(true)
    .diskCacheStrategy( DiskCacheStrategy.NONE )
    .into(imageView);

上面這段代碼將內存緩存和磁盤緩存都禁用了,這裏使用枚舉 DiskCacheStrategy.NONE 將磁盤緩存禁用了,這裏涉及到了自定義磁盤緩存行爲,咱們接下來就講解這個。

自定義磁盤緩存行爲

使用 DiskCacheStrategy 能夠爲 Glide 配置磁盤緩存行爲。Glide 的磁盤緩存比較複雜,這也是在圖片加載能夠比 Picasso 的緣由(之一)。Picasso 只緩存了全尺寸的圖片,而 Glide 的不一樣之處在於,Glide 不只緩存了全尺寸的圖,還會根據 ImageView 大小所生成的圖也會緩存起來。好比,請求一個 800x600 的圖加載到一個 400x300 的 ImageView 中,Glide默認會將這原圖還有加載到 ImageView 中的 400x300 的圖也會緩存起來。

DiskCacheStrategy 的枚舉意義:

  • DiskCacheStrategy.NONE 什麼都不緩存
  • DiskCacheStrategy.SOURCE 只緩存全尺寸圖
  • DiskCacheStrategy.RESULT 只緩存最終的加載圖
  • DiskCacheStrategy.ALL 緩存全部版本圖(默認行爲

這只是舉個例子而已

Glide.with(context)
    .load(url)
    .diskCacheStrategy( DiskCacheStrategy.SOURCE )
    .into(imageView);

圖片請求的優先級

同一時間加載多個圖片,App 將難以免這種狀況。若是這個時候咱們但願用戶的體驗更好,每每會選擇先加載對於用戶更加劇要的圖片。Glide 能夠調用 .priority() 方法配合 Priority 枚舉來設置圖片加載的優先級。

//設置 HIGH 優先級
Glide.with( context )
    .load( highPriorityImageUrl )
    .priority (Priority.HIGH )
    .into( imageView );
//設置 LOW 優先級
Glide.with( context )
    .load( lowPriorityImageUrl )
    .priority( Priority.LOW )
    .into( imageView );
  • Priority.LOW
  • Priority.NORMAL
  • Priority.HIGH
  • Priority.IMMEDIAT

這裏有一點須要注意,優先級並非徹底嚴格遵照的。Glide 將會用他們做爲一個準則,儘量的處理這些請求,可是不能保證全部的圖片都會按照全部要求的順序加載。

顯示 Gif 和 Video

顯示 GIf 對於 Glide 來講一個比較特別的功能(至少 Picasso 暫時還不行)並且使用起來很是簡單

String gifUrl = "http://i2.mhimg.com/M00/0E/AE/CgAAilTPWJ2Aa_EIACcMxiZi5xE299.gif";
Glide.with( context )
    .load( gifUrl )
    .placeholder( R.drawable.default )
    .error( R.drawable.error )
    .into( imageView );

這段代碼還有點問題,若是加載的不是一張 gif 圖的話,是沒有辦法顯示的。

Glide.with( context )
    .load( gifUrl )
    .asGif()
    .error( R.drawable.error )
    .into( imageView );

作以上修改,若是圖片類型不是 Gif 圖的話就會看成 load 失敗來處理,所以 error() 會被回調。即便這個url的圖片是好的,也是不會顯示的。固然,若是你想顯示 Gif 但只是向現實靜態的圖片你就能夠這麼作

Glide.with( context )
    .load( gifUrl )
    .asBitmap()
    .error( R.drawable.error )
    .into( imageView );

僅僅是顯示 Gif 的第一幀圖像,這樣就能夠保證圖片的正常顯示了。

還有一個神奇的功能,Glide 還能顯示視頻!But...只可以顯示手機本地的視頻,要是向現實網絡上的視頻的話,仍是另尋他法吧!

String filePath = "/storrage/emulated/0/Pictures/video.mp4";
Glide.with( context )
    .load( Uri.fromFile( new File( filePath ) ) )
    .into( imageView );

Glide 的基礎使用就講解到這了。

(三)進階使用

Target篇

到如今爲止,咱們所涉及到的代碼都是直接加載圖片到 ImageView 中。Glide 隱藏作了全部的網絡請求和後臺的線程處理,圖片準備好以後切回到 UI 線程刷新 ImageView。也就是說 ImageView 在咱們代碼的鏈式結構中成爲了最後一步,可是若是咱們須要獲取到 Bitmap 自己
的話咱們就須要用到 Target 了。Target 其實就是整個圖片的加載的生命週期,因此咱們就能夠經過它在圖片加載完成以後獲取到 Bitmap。

其實對於 Target 能夠簡單的理解爲回調,自己就是一個 interface,Glide自己也爲咱們提供了不少 Target

全部Targets

SimpleTarget

直接上代碼

private SimpleTarget<Bitmap> mSimpleTarget = new SimpleTarget<Bitmap>() {
    @Override
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> animation) {
        mImageView.setImageBitmap(resource);
    }
};

private void loadImageSimpleTarget() {
    Glide.with( thi s)
        .load( mUrl )
        .asBitmap()
        .into( mSimpleTarget );
}

首先建立了一個 SimpleTarget 的對象而且實現了 onResourceReady() 方法,看方法名能知道是圖片加載完以後會調用該方法,參數就有咱們須要的 Bitmap 。而使用 SimpleTarget 的對象的時候就像使用 ImageView 同樣,做爲參數傳給 into() 方法就好了,Glide 會內部去處理並返回結果給任何一個對象。這裏咱們爲了防止加載 Gif 、 Video 或者一些位置資源時與 mSimpleTarget 衝突,因此咱們調用了 asBitmap() 方法,使其只能返回 Bitmap 對象。

這裏就有個問題了,若是我須要改變圖片的大小怎麼辦?這點小問題 Glide 仍是有考慮到的,加入原尺寸 1000x1000 的圖片,咱們顯示的時候只須要是 500x500 的尺寸來節省時間和內存,你能夠在 SimpleTarget 的回調聲明中指定圖片的大小。

private SimpleTarget<Bitmap> mSimpleTarget = new SimpleTarget<Bitmap>(500,500) {
    @Override
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> animation) {
        mImageView.setImageBitmap(resource);
    }
};

從代碼中能夠看到 SimpleTarget 的對象的聲明沒有使用匿名對象,而是單獨的聲明瞭一個變量,這裏是故意這麼作的,若是使用匿名內部類的方式建立 SimpleTarget 的對象,這樣會增大該對象在 Glide 完成圖片請求以前就被回收的可能性。

還記得前面說過 with() 方法傳入 Activity 或者 Fragment 時 Glide 的圖片加載會與他們的生命週期關聯起來,可是若是咱們使用 Target 的話,這個 Target 就有可能獨立於他們的生命週期之外,這時候咱們就須要使用 context.getApplicationContext() 的上下文了,這樣只有在應用徹底中止時 Glide 纔會殺死這個圖片請求。代碼以下

Glide.with(mContext.getApplicationContext())
        .load(mUrl)
        .asBitmap()
        .into(target);

ViewTarget

當咱們使用 Custom View 時,Glide 並不支持加載圖片到自定義 view 中的,使用 ViewTarget 更容易實現。

public class CustomView extends FrameLayout {
    private ImageView mImageView;

    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mImageView = new ImageView(getContext());
        addView(mImageView , LayoutParams.MATCH_PARENT , LayoutParams.MATCH_PARENT);
    }

    public void setImage(Drawable drawable){
        mImageView.setImageDrawable(drawable);
    }
}

上面這個例子就沒有辦法直接使用 .into() ,若是咱們使用 ViewTarget 實現呢!

public void loadImageTarget(Context context){
    CustomView mCustomView = (CustomView) findViewById(R.id.custom_view);

    ViewTarget viewTarget = new ViewTarget<CustomView,GlideDrawable>( mCustomView ) {
        @Override
        public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
            this.view.setImage(resource);
        }
    };

    Glide.with(context)
            .load(mUrl)
            .into(viewTarget);
}

在 target 的 onResourceReady 回調方法中使用自定義 view 本身的方法去設置圖片,能夠看到在建立 ViewTarget 的時候傳入了 CustomView 的對象。

還有其餘Target的使用這裏就不一一講述了,例如 AppWidgetTarget 、 NotificationTarget ...

Transformations篇

圖片顯示以前咱們可能還須要對圖片進行處理操做,好比:圖片切圓角,灰階處理等等;這些需求咱們經過 Transformations 操做 bitmap 來實現,咱們能夠修改圖片的任意屬性:尺寸,範圍,顏色,像素位置等等。其實咱們以前已經提到過兩個 Transformation 了,即 fitCenter 和 centerCrop ,這兩個是 Glide 已經實現的。

接下來就要講講怎麼樣來實現本身的 Transformation ,咱們須要建立一個類去實現 Transformation 接口,可是要實現這個方法仍是比較複雜的,接口中 transform 方法提供的參數 Resource<T> resource 不是那麼好處理的。若是你只是想要對圖片(不是 Gif 和 video)作常規的 bitmap 轉換,咱們推薦你使用抽象類 BitmapTransformation。它簡化了不少的實現,這應該能覆蓋 95% 的應用場景啦。

下面的代碼實現了對圖片切圓角的操做,其中 getId() 方法描述了這個 Transformation 的惟一標識,爲避免意外咱們須要確保它是惟一的。

public class RoundTransformation extends BitmapTransformation {
    private float radius = 0f;

    public RoundTransformation(Context context) {
        this(context, 4);
    }

    public RoundTransformation(Context context, int px) {
        super(context);
        this.radius = px;
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return roundCrop(pool, toTransform);
    }

    private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null)
            return null;

        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }

    @Override
    public String getId() {
        return getClass().getName() + Math.round(radius);
    }

}

如今咱們有了本身的 Transformation 就能夠來看看怎麼使用了。

調用 .transform() 方法,將自定義的 Transformation 的對象做爲參數傳遞進去就可使用你的 Transformation 了,這裏也可使用 .bitmaoTransform() 可是它只能用於 bitmap 的轉換。

Glide.with(context)
    .load(mUrl)
    .transform(new RoundTransformation(context , 20))
    //.bitmapTransform( new RoundTransformation(context , 20) )
    .into(mImageView);

若是咱們須要同時執行多個 Transformation 的話,咱們不能使用鏈式的形式屢次調用 .transform() 或 .bitmapTransform() 方法,即便你調用了,以前的配置就會被覆蓋掉!咱們能夠直接傳遞多個轉換對象給 .transform() 或 .bitmapTransform() 。

Glide.with(context)
    .load(mUrl)
    .transform(new RoundTransformation(context , 20) ,  new RotateTransformation(context , 90f))
    .into(mImageView);

這段代碼中咱們把一個圖片切圓角,而後作了順時針旋轉90度處理。

下面是旋轉處理的代碼

public class RotateTransformation extends BitmapTransformation {

    private float rotateRotationAngle = 0f;

    public RotateTransformation(Context context, float rotateRotationAngle) {
        super( context );
        this.rotateRotationAngle = rotateRotationAngle;
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        Matrix matrix = new Matrix();

        matrix.postRotate(rotateRotationAngle);

        return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);
    }

    @Override
    public String getId() {
        return getClass().getName() + Math.round(rotateRotationAngle);
    }
}

注:這裏須要注意一點 .centerCrop() 和 .fitCenter() 也都是 Transformation 因此也是遵循同時使用多個 Transformation 的規則的,即:當你使用了自定義轉換後你就不能使用 .centerCrop() 或 .fitCenter() 了。

這裏有一個 GLide Transformations 的庫,它提供了不少 Transformation 的實現,很是值得去看,沒必要重複造輪子對吧!
glide-transformations
這個庫有兩個不一樣的版本,擴展版本包含了更多的 Transformation ,它是經過設備的 GPU 來計算處理的,須要有額外的依賴,因此這兩個版本的設置有一點不一樣。仍是根據須要再決定使用那個版本吧!

Animate篇

從圖像到圖像的平滑過渡是很是重要,Glide 中有一個標準動畫去柔軟的在你的 UI 中改變,可是咱們如今但願設置本身的動畫。

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">

    <scale
        android:duration="@android:integer/config_longAnimTime"
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1"/>
</set>

這是個 XML 動畫縮放動畫,圖片剛開始小的,而後逐漸增大到原尺寸。咱們如今要應用到 Glide 加載圖片中去,調用 .animate() 方法傳入 XML 動畫的 id 便可。

Glide.with(context)
    .load(mUrl)
    .transform(new RoundTransformation(this , 20))
    .animate( R.anim.zoom_in )
    .into(mImageView);

這種加載方式用在常規的 ImageView 上是沒有問題的,但若是使用的 Target 是一些自定義的時候就無法好好的實現了。這時候咱們就能夠經過傳入實現了 ViewPropertyAnimation.Animator 接口的類對象來實現。

ViewPropertyAnimation.Animator animator = new ViewPropertyAnimation.Animator() {
    @Override
    public void animate(View view) {
        view.setAlpha( 0f );

        ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f );
        fadeAnim.setDuration( 2500 );
        fadeAnim.start();
    }
};

而後,咱們只須要在 Glide 請求中設置這個動畫對象就ok了

Glide.with(context)
    .load(mUrl)
    .animate( animator )
    .into(viewTarget);

在 animate(View view) 中你的動畫對象方法中, 你能夠作任何你想要對視圖作的事情。自由的用你建立的動畫吧。

Modules篇

Glide 的 Module 是一個能夠全局改變 Glide 的行爲的東西,爲了定製 Glide 的行爲咱們要去實現 interface GlideModule 來寫咱們本身的代碼。

public class ExampleModule implements GlideModule{
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // todo
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        // todo
    }
}

能夠看到 GlideModule 爲咱們提供了兩個方法,這裏咱們主要使用的是 applyOptions(Context context, GlideBuilder builder) , 咱們本身的須要從新定義的代碼寫在該方法裏就能夠了。而後咱們還須要去 AndroidManifest.xml 中使用 meta 聲明咱們上面實現的 Module

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mrtrying.demoglide">

    <application>

        <meta-data
            android:name="com.mrtrying.demoglide.module.ExampleModule"
            android:value="GlideModule" />

        ...

    </application>

    ...

</manifest>

到這裏咱們就完成了 ExampleModule 的聲明,Glide 將會在工做是使用咱們所定義的 Module

TIPS

  • 咱們須要將 android:name 屬性改爲 包名+類名 的形式,這樣的引用纔是正確的。若是你想刪掉 Glide Module,只須要刪除在 AndroidManifest.xml 中的聲明就能夠了。Java 類能夠保存,說不定之後會用呢。若是它沒有在 AndroidManifest.xml 中被引用,那它不會被加載或被使用。

  • 定製 module 的話 Glide 會有這樣一個優勢:你能夠同時聲明多個 Glide module。Glide 將會(沒有特定順序)獲得全部的聲明 module。由於你當前不能定義順序,請確保定製不會引發衝突!

這個過程走通了,接下來咱們來看看是怎麼自定義的。applyOptions(Context context, GlideBuilder builder) 中有兩個參數, 咱們經過使用 GlideBuilder 來實現咱們的需求。先看看 GlideBuilder 中可用的方法

  • .setMemoryCache(MemoryCache memoryCache)
  • .setBitmapPool(BitmapPool bitmapPool)
  • .setDiskCache(DiskCache.Factory diskCacheFactory)
  • .setDiskCacheService(ExecutorService service)
  • .setResizeService(ExecutorService service)
  • .setDecodeFormat(DecodeFormat decodeFormat)

能夠看到,這個 GlideBuilder 對象給你訪問了 Glide 重要的核心組件。接下來咱們就要試着去使用這些方法

增長 Glide 的圖片質量

在 Android 中有兩個主要的方法對圖片進行解碼:ARGB_8888 和 RGB_565 。前者爲每一個像素使用4個字節,後者每一個像素僅使用2個字節。ARGB_8888 的有時就是圖像質量更高以及能儲存一個 alpha 通道。 Picasso 使用的就是 ARGB_8888 , Glide 默認使用低質量的 RGB_565 ,可是如今你就可使用 Glide module 來改變圖片解碼規則。就象這樣

public class QualityModule implements GlideModule{
    @Override
    public void applyOptions(Context context , GlideBuilder builder){
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

    @Override
    public void registerComponents(Context context , Glide glide){
        // nothing to do here
    }
}

這樣咱們就簡單的增長了 Glide 的圖片質量。

每每咱們還會遇到一些狀況,但願 Glide 可使用咱們本身的網絡框架,咱們就須要作一些事情來實現這個需求了。Glide 的開發者不強制設置網絡庫給你,因此Glide能夠說和 HTTPS 無關。理論上,它能夠與任何的網絡庫實現,只要覆蓋了基本的網絡能力就行。一樣是須要實現 Glide 的 ModuleLoader 的接口,爲了讓咱們更加易用,Glide 爲 OkHttp 和 Volley 兩個網絡庫提供了實現。

假設我要集成 OkHttp 做爲 Glide 的網絡庫,我能夠手動實現一個 GlideModule 也能夠在 build.gradle 中添加依賴:

dependencies{
    //...
    
    // Glide
    compile 'com.github.bumptech.glide:glide:3.7.0'

    // Glide's OkHttp Integration
    compile 'com.github.bumptech.glide:okhttp-integration:1.4.0@aar'
    compile 'com.squareup.okhttp:okhttp:3.2.0'
}

Gradle 會自動合併必要的 GlideModule 到你的 AndroidManifest.xml , Glide 會承認在 manifest 中存在,而後使用 OkHttp 作到的全部網絡鏈接。

做者:MrTrying 連接:https://www.jianshu.com/p/7ce7b02988a4 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索