1. 程式人生 > >Android圖片載入框架最全解析(六),探究Glide的自定義模組功能(筆記)

Android圖片載入框架最全解析(六),探究Glide的自定義模組功能(筆記)

參考原文:Android圖片載入框架最全解析(六),探究Glide的自定義模組功能

自定義模組的基本用法

自定義模組功能可以將更改Glide配置,替換Glide元件等操作獨立出來,使得我們能輕鬆地對Glide的各種配置進行自定義,並且又和Glide的圖片載入邏輯沒有任何交集,這也是一種低耦合程式設計方式的體現

public class MyGlideModule implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder)
{ } @Override public void registerComponents(Context context, Glide glide) { } }
<manifest>

    ...

    <application>

        <meta-data
            android:name="com.example.glidetest.MyGlideModule"
            android:value="GlideModule" />

        ...

    </
application
>
</manifest>

自定義模組的原理

public class Glide {

    private static volatile Glide glide;

    ...

    public static Glide get(Context context) {
        if (glide == null) {
            synchronized (Glide.class) {
                if (glide == null) {
                    Context applicationContext =
context.getApplicationContext(); List<GlideModule> modules = new ManifestParser(applicationContext).parse(); GlideBuilder builder = new GlideBuilder(applicationContext); for (GlideModule module : modules) { module.applyOptions(applicationContext, builder); } glide = builder.createGlide(); for (GlideModule module : modules) { module.registerComponents(applicationContext, glide); } } } } return glide; } ... }

createGlide()方法中建立任何物件的時候都做了一個空檢查,只有在物件為空的時候才會去建立它的例項。也就是說,如果我們可以在applyOptions()方法中提前就給這些物件初始化並賦值,那麼在createGlide()方法中就不會再去重新建立它們的例項了,從而也就實現了更改Glide配置的功能。

更改Glide配置

setMemoryCache()
用於配置Glide的記憶體快取策略,預設配置是LruResourceCache。
setBitmapPool()
用於配置Glide的Bitmap快取池,預設配置是LruBitmapPool。
setDiskCache()
用於配置Glide的硬碟快取策略,預設配置是InternalCacheDiskCacheFactory。
setDiskCacheService()
用於配置Glide讀取快取中圖片的非同步執行器,預設配置是FifoPriorityThreadPoolExecutor,也就是先入先出原則。
setResizeService()
用於配置Glide讀取非快取中圖片的非同步執行器,預設配置也是FifoPriorityThreadPoolExecutor。
setDecodeFormat()
用於配置Glide載入圖片的解碼模式,預設配置是RGB_565。
其實Glide的這些預設配置都非常科學且合理,使用的快取演算法也都是效率極高的,因此在絕大多數情況下我們並不需要去修改這些預設配置,這也是Glide用法能如此簡潔的一個原因。
但是Glide科學的預設配置並不影響我們去學習自定義Glide模組的功能,因此總有某些情況下,預設的配置可能將無法滿足你,這個時候就需要我們自己動手來修改預設配置了。

Glide預設的硬碟快取策略使用的是InternalCacheDiskCacheFactory,這種快取會將所有Glide載入的圖片都儲存到當前應用的私有目錄下。這是一種非常安全的做法,但同時這種做法也造成了一些不便,因為私有目錄下即使是開發者自己也是無法檢視的.們就嘗試使用這個ExternalCacheDiskCacheFactory來替換預設的InternalCacheDiskCacheFactory,從而將所有Glide載入的圖片都快取到SD卡上。

public class MyGlideModule implements GlideModule {

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
    }

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

    }

}

InternalCacheDiskCacheFactory和ExternalCacheDiskCacheFactory的預設硬碟快取大小都是250M。也就是說,如果你的應用快取的圖片總大小超出了250M,那麼Glide就會按照DiskLruCache演算法的原則來清理快取的圖片。

public class MyGlideModule implements GlideModule {

    public static final int DISK_CACHE_SIZE = 500 * 1024 * 1024;

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, DISK_CACHE_SIZE));
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

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

    }

}

ExternalCacheDiskCacheFactory的預設快取路徑是在sdcard/Android/包名/cache/image_manager_disk_cache目錄當中

我們都知道Glide和Picasso的用法是非常相似的,但是有一點差別卻很大。Glide載入圖片的預設格式是RGB_565,而Picasso載入圖片的預設格式是ARGB_8888。ARGB_8888格式的圖片效果會更加細膩,但是記憶體開銷會比較大。而RGB_565格式的圖片則更加節省記憶體,但是圖片效果上會差一些

替換Glide元件

預設情況下,Glide使用的是基於原生HttpURLConnection進行訂製的HTTP通訊元件,但是現在大多數的Android開發者都更喜歡使用OkHttp,因此將Glide中的HTTP通訊元件修改成OkHttp的這個需求比較常見

在Glide類的構造方法當中

register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());

這句程式碼就表示,我們可以使用Glide.with(context).load(new GlideUrl(“url…”)).into(imageView)的方式來載入圖片,而HttpUrlGlideUrlLoader.Factory則是要負責處理具體的網路通訊邏輯。如果我們想要將Glide的HTTP通訊元件替換成OkHttp的話,那麼只需要在自定義模組當中重新註冊一個GlideUrl型別的元件就行了。
HttpUrlGlideUrlLoader.Factory
HttpUrlFetcher

public class MyGlideModule implements GlideModule {

    ...

    @Override
    public void registerComponents(Context context, Glide glide) {
        glide.register(GlideUrl.class, InputStream.class, new OkHttpGlideUrlLoader.Factory());
    }

}

更簡單的元件替換

支援OkHttp3之外,還支援OkHttp2和Volley。

dependencies {
    compile 'com.squareup.okhttp3:okhttp:3.9.0'
    compile 'com.github.bumptech.glide:okhttp3-integration:[email protected]'
}