1.glide的網(wǎng)絡(luò)請求用的是什么?
httpurlconnection
2.glide如何和activity同步生命周期?
通過創(chuàng)建一個(gè)隱藏的fragment掖疮,同步activity的生命周期缠局。如果傳入的上下文是application,那么glide的請求生命周期和應(yīng)用一樣長依许。
3.glide的緩存key是如何生成的?
1.緩存原圖的話key主要是有url組成
2.緩存轉(zhuǎn)換后的圖的key是由width缀蹄,height峭跳,encoder等十個(gè)參數(shù)生成。
4.glide內(nèi)存緩存怎么實(shí)現(xiàn)的缺前?
內(nèi)存緩存由兩部分組成坦康,由Lrucache算法和弱引用activiResources 一個(gè)hashMap集合組成,這個(gè)集合存儲正在使用的圖片诡延。這個(gè)hashMap集合可以確保圖片不會被lrucache算法回收掉滞欠。也就是說glide將正在使用的圖片用activeResources保存,不在使用的用LruCache來保存肆良。
5.glide的硬盤緩存
glide磁盤緩存可以緩存原始圖片和轉(zhuǎn)換后的圖片筛璧,如果是原始圖片,那么緩存key就是id和signature惹恃,如果緩存的是轉(zhuǎn)換后的圖片那緩存key是由寬高等十多個(gè)參數(shù)組成夭谤。磁盤緩存使用的DiskLrucache。
6.glide緩存失效問題
當(dāng)我們請求一張圖片的url后面加入了可變token的時(shí)候巫糙,那么我們glide的緩存就會失效朗儒,因?yàn)榫彺鎘ey的組成就有url,解決這個(gè)問題可以自定義GlideUrl参淹,重寫getCacheKey()這個(gè)方法醉锄。
7.glide的預(yù)加載功能
glide提供了預(yù)加載接口,就是preLoad()方法浙值,這個(gè)方法有兩個(gè)重載恳不,一個(gè)是加載原始圖片大小,一個(gè)是指定寬和高开呐,如果使用preLoad()預(yù)加載圖片烟勋,那么需要指定緩存策略為原圖规求,否則再真正顯示用into的時(shí)候,還是會去網(wǎng)絡(luò)加載卵惦,因?yàn)榫彺鎘ey不一致阻肿,獲取不到緩存圖片。當(dāng)然into加載的時(shí)候也需要指定緩存策略為緩存原圖沮尿。
8.如何獲取緩存圖片的路徑丛塌。
要想獲取一個(gè)緩存圖片的路徑可以使用downloadOnly()方法,這個(gè)方法會執(zhí)行下載圖片的邏輯蛹找,并且下載i 之后是一個(gè)文件,可以獲取路徑哨坪,必須在子線程開啟下載庸疾。
public void downloadImage(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
final Context context = getApplicationContext();
FutureTarget<File> target = Glide.with(context)
.load(url)
.downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
final File imageFile = target.get();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, imageFile.getPath(), Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
9.glide的錯(cuò)誤調(diào)試
glide有一個(gè)listener()方法,這個(gè)方法在into之前或者preLoad()之前調(diào)用,requestListener中的兩個(gè)方法都有返回值当编,當(dāng)都返回false的時(shí)候包括錯(cuò)誤展位圖和正常圖片顯示才會繼續(xù)執(zhí)行届慈。
Glide.with(this)
.load(url)
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target,
boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model,
Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
return false;
}
})
.into(imageView);
}
10.glide圖片變換導(dǎo)致的充滿全屏幕問題
可以通過設(shè)置dontTrasform() or override(Target.SIZE_ORIGINSL,Target.SIZE_ORIGINSL) 方法解決。
11.glide模塊的自定義
glide支持對一些功能的自定義忿偷,以及一些組建的替換金顿。
public class MyGlideModule implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
通過實(shí)現(xiàn)GlideModule可以實(shí)現(xiàn)一些功能的自定義和一些自定義組建的替換,applyOptions方法中實(shí)現(xiàn)功能的自定義鲤桥,registerComponents這個(gè)方法實(shí)現(xiàn)自定義組建的替換揍拆,這兩個(gè)方法互相獨(dú)立使用。
下面是glide允許自定義的功能列表:
setMemoryCache()
用于配置Glide的內(nèi)存緩存策略茶凳,默認(rèn)配置是LruResourceCache嫂拴。
setBitmapPool()
用于配置Glide的Bitmap緩存池,默認(rèn)配置是LruBitmapPool贮喧。
setDiskCache()
用于配置Glide的硬盤緩存策略筒狠,默認(rèn)配置是InternalCacheDiskCacheFactory。
setDiskCacheService()
用于配置Glide讀取緩存中圖片的異步執(zhí)行器箱沦,默認(rèn)配置是FifoPriorityThreadPoolExecutor辩恼,也就是先入先出原則。
setResizeService()
用于配置Glide讀取非緩存中圖片的異步執(zhí)行器谓形,默認(rèn)配置也是FifoPriorityThreadPoolExecutor灶伊。
setDecodeFormat()
用于配置Glide加載圖片的解碼模式,默認(rèn)配置是RGB_565寒跳。
其中最常見的就是自定義緩存路徑和自定義圖片編碼模式
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) {
}
}
上面這段代碼實(shí)現(xiàn)了將glide的緩存文件緩存到sd卡谁帕,并且指定圖片編碼模式是ARGB_8888,Android默認(rèn)是RGB_565.
替換glide組件
glide中可替換的組件有如下:
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
...
register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
register(File.class, InputStream.class, new StreamFileLoader.Factory());
register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(int.class, InputStream.class, new StreamResourceLoader.Factory());
register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
register(String.class, InputStream.class, new StreamStringLoader.Factory());
register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());
...
}
一般主要可能替換的組件就是網(wǎng)絡(luò)組件,所以glide給我們提供了非常簡單的方式去繼承其他的網(wǎng)絡(luò)庫冯袍,比如okhttp:
dependencies {
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.github.bumptech.glide:okhttp3-integration:1.5.0@aar'
}
只需要加入這樣的依賴我們的網(wǎng)絡(luò)庫就替換成了okhttp匈挖。
glide如果將結(jié)果切換回主線程:
通過mainLooper()創(chuàng)建了handler碾牌,通過handler實(shí)現(xiàn)切換回主線程!
參考資料:
glide源碼
郭霖glide源碼分析