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]'
}