前言:
前面學習了Glide的簡單使用(Android圖片快取之初識Glide),今天來學習一下Glide稍微複雜一點的使用。
圖片快取相關部落格地址:
GlideModule使用:
GlideModule 是一個抽象方法,全域性改變 Glide 行為的一個方式,通過全域性GlideModule 配置Glide,用GlideBuilder
設定選項,用Glide註冊ModelLoader等。
1.)自定義一個GlideModule
public class MyGlideModule implements GlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { // Apply options to the builder here. } @Override public void registerComponents(Context context, Glide glide) { // register ModelLoaders here. } }
2.)AndroidManifest.xml註冊
<manifest ...> <!-- ... permissions --> <application ...> <meta-data android:name="com.mypackage.MyGlideModule" android:value="GlideModule" /> <!-- ... activities and other components --> </application> </manifest>
3.)新增混淆處理
-keepnames class com.mypackage.MyGlideModule
# or more generally:
#-keep public class * implements com.bumptech.glide.module.GlideModule
4.)多個GlideModule衝突問題
GlideModule不能指定呼叫順序,所以應該避免不同的GlideModule之間有衝突的選項設定,可以考慮將所有的設定都放到一個GlideModule裡面,或者排除掉某個manifest檔案的某個Module,程式碼如下:
<meta-data android:name=”com.mypackage.MyGlideModule” tools:node=”remove” />
GlideBuilder
設定選項:
1.)設定Glide記憶體快取大小
int maxMemory = (int) Runtime.getRuntime().maxMemory();//獲取系統分配給應用的總記憶體大小 int memoryCacheSize = maxMemory / 8;//設定圖片記憶體快取佔用八分之一 //設定記憶體快取大小 builder.setMemoryCache(new LruResourceCache(memoryCacheSize));
獲取預設的記憶體使用計算函式
MemorySizeCalculator calculator = new MemorySizeCalculator(context); int defaultMemoryCacheSize = calculator.getMemoryCacheSize(); int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
2.)設定Glide磁碟快取大小
File cacheDir = context.getExternalCacheDir();//指定的是資料的快取地址 int diskCacheSize = 1024 * 1024 * 30;//最多可以快取多少位元組的資料 //設定磁碟快取大小 builder.setDiskCache(new DiskLruCacheFactory(cacheDir.getPath(), "glide", diskCacheSize));
也可以通過如下兩種方式
//存放在data/data/xxxx/cache/ builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide", diskCacheSize)); //存放在外接檔案瀏覽器 builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, "glide", diskCacheSize));
3.)設定圖片解碼格式
//設定圖片解碼格式 builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
預設格式RGB_565使用記憶體是ARGB_8888的一半,但是圖片質量就沒那麼高了,而且不支援透明度
4.)設定快取記憶體大小
//設定BitmapPool快取記憶體大小 builder.setBitmapPool(new LruBitmapPool(memoryCacheSize));
5.)設定一個用來檢索cache中沒有的Resource的ExecutorService
為了使縮圖請求正確工作,實現類必須把請求根據Priority優先順序排好序。
builder.setDiskCacheService(ExecutorService service);
builder.setResizeService(ExecutorService service);
使用ModelLoader自定義資料來源:
例如我們使用了七牛雲端儲存,要根據不同的要求請求不同尺寸不同質量的圖片,這時我們就可以使用自定義資料來源
1.)定義處理URL介面
public interface IDataModel { String buildDataModelUrl(int width, int height); }
2.)實現處理URL介面
JpgDataModel
public class JpgDataModel implements IDataModel { private String dataModelUrl; public JpgDataModel(String dataModelUrl) { this.dataModelUrl = dataModelUrl; } @Override public String buildDataModelUrl(int width, int height) { //http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg?imageView2/1/w/200/h/200/format/jpg return String.format("%s?imageView2/1/w/%d/h/%d/format/jpg", dataModelUrl, width, height); } }
WebpDataModel
public class WebpDataModel implements IDataModel { private String dataModelUrl; public WebpDataModel(String dataModelUrl) { this.dataModelUrl = dataModelUrl; } @Override public String buildDataModelUrl(int width, int height) { //http://78re52.com1.z0.glb.clouddn.com/resource/gogopher.jpg?imageView2/1/w/200/h/200/format/webp return String.format("%s?imageView2/1/w/%d/h/%d/format/webp", dataModelUrl, width, height); } }
3.)實現ModelLoader
public class MyDataLoader extends BaseGlideUrlLoader<IDataModel> { public MyDataLoader(Context context) { super(context); } public MyDataLoader(ModelLoader<GlideUrl, InputStream> urlLoader) { super(urlLoader, null); } @Override protected String getUrl(IDataModel model, int width, int height) { return model.buildDataModelUrl(width, height); } /** */ public static class Factory implements ModelLoaderFactory<IDataModel, InputStream> { @Override public ModelLoader<IDataModel, InputStream> build(Context context, GenericLoaderFactory factories) { return new MyDataLoader(factories.buildModelLoader(GlideUrl.class, InputStream.class)); } @Override public void teardown() { } } }
4.)根據不同的要求採用不同的策略載入圖片
//載入jpg圖片 Glide.with(this).using(new MyDataLoader(this)).load(new JpgDataModel(imageUrl)).into(imageView); //載入webp圖片 Glide.with(this).using(new MyDataLoader(this)).load(new WebpDataModel(imageUrl)).into(imageView);
5.)如何跳過.using()
public class MyGlideModule implements GlideModule { ... @Override public void registerComponents(Context context, Glide glide) { glide.register(IDataModel.class, InputStream.class, new MyUrlLoader.Factory()); } }
上面的實現跳過using()
//載入jpg圖片 Glide.with(this).load(new JpgDataModel(imageUrl)).into(imageView); //載入webp圖片 Glide.with(this).load(new WebpDataModel(imageUrl)).into(imageView);
使用signature()實現自定義cacheKey:
Glide 以 url、viewwidth、viewheight、螢幕的解析度等做為聯合key,官方api中沒有提供刪除圖片快取的函式,官方提供了signature()方法,將一個附加的資料加入到快取key當中,多媒體儲存資料,可用MediaStoreSignature類作為識別符號,會將檔案的修改時間、mimeType等資訊作為cacheKey的一部分,通過改變key來實現圖片失效相當於軟刪除。
1.)使用StringSignature
Glide.with(this).load(yourFileDataModel).signature(new StringSignature("1.0.0")).into(imageView);
2.)使用MediaStoreSignature
Glide.with(this) .load(mediaStoreUri).signature(new MediaStoreSignature(mimeType, dateModified, orientation)).into(view);
3.)使用自定義Signature
public class IntegerVersionSignature implements Key { private int currentVersion; public IntegerVersionSignature(int currentVersion) { this.currentVersion = currentVersion; } @Override public boolean equals(Object o) { if (o instanceof IntegerVersionSignature) { IntegerVersionSignature other = (IntegerVersionSignature) o; return currentVersion = other.currentVersion; } return false; } @Override public int hashCode() { return currentVersion; } @Override public void updateDiskCacheKey(MessageDigest md) { messageDigest.update(ByteBuffer.allocate(Integer.SIZE) .putInt(signature).array()); } }
小結:
今天學了Glide的一些自定義擴充套件知識,接下來學習一下Glide與OKHttp的結合,已經簡單探析一下內部使用。