Glide Module 案例: 自定义缓存
原文:Glide Module Example: Customize Caching
作者:Norman Peitek
翻译:Dexter0218
在上篇文章中,我们学习了使用一个定制的HTTP client接收self-signed HTTPS证书设置到Glide module里的过程。本文,停留在一个低水平,看一下定制Glide缓存部分的案例。
Glide 系列概览
- 入门简介
- 高级加载
- 适配器(ListView, GridView)
- 占位图& 淡入淡出动画
- 图片大小 & 缩放
- 播放GIF & 视频
- 缓存基础
- 请求优先级
- 缩略图
- 回调:定制view中使用SimpleTarget和ViewTarget
- 通知栏和桌面小控件的图片加载
- 异常: 调试和报错处理
- 自定义变换
- 用animate()定制动画
- 整合网络协议栈
- 用Modules定制Glide
- Glide Module 案例: 接受自签名HTTPS证书
- Glide Module 案例: 自定义缓存
- Glide Module 案例: 通过加载自定义大小图片优化
- 动态使用 Model Loaders
- 如何旋转图片
- 系列综述
自定义内存缓存 ##
希望你已经读过缓存的基础知识和Glide module的文章。否则下面的代码可能看不懂。如果你准备好了,那就开始看吧。
既然我们自定义Glide,我们需要创建一个Glide module。在前面的文章中介绍过,applyOptions
方法提供了访问GlideBuilder
对象的方法。GlideBuilder
方法提供了几个方法去自定义Glide的缓存。首先,看看内存缓存。
内存缓存是在设备的RAM中保存图片。由于没有IO操作,所以非常快。不利的是由于RAM的大小是收到限制的。在小内存缓存和大内存缓存之间找到一个合适的平衡点并不简单。Glide内存使用MemorySizeCalculator
类去决定内存缓存和bitmap池的大小。Bitmap池保存着在你的应用heap里放着的图片。Bitmap池的正确大小是很重要的,防止太多重新分配图片,这样可以让垃圾回收器的生命更简单。
幸运地,你已经接触到Glide的MemorySizeCalculator
类和默认的计算:
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
如果你想要使用默认值作为基线并调整,上面的代码是非常有用的。例如,如果你想要你的app比默认多20%的缓存,使用上面的变量来计算它们:
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
由于我们已经指出我们的内存缓存和Bitmap池的大小,我们可以最终可以编码我们的Glide module。在applyOption()
方法,我们可以在GlideBuilder
对象上调用合适的方法:
public class CustomCachingGlideModule implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);
builder.setMemoryCache( new LruResourceCache( customMemoryCacheSize );
builder.setBitmapPool( new LruBitmapPool( customBitmapPoolSize );
}
@Override public void registerComponents(Context context, Glide glide) {
// nothing to do here
}
}
在applyOptions()
方法的最后两行可以看出,我们不能直接设置大小。我们创建一个LruResourceCache
和LruBitmapPool
类的实例。这个两个都是Glide的默认实现。这样,如果你想要调整大小,你可以只通过传递一个不同大小的值到构造器继续使用它们。
自定义磁盘缓存
调整磁盘缓存的工作也类似,只是我们需要多做一个决定。磁盘缓存可以存在app的私有目录下(换句话说,除非你自己的app,其它app访问不了)。不然,磁盘缓存可以存在外部,公共路径(更多信息,请看存储方案)。默认设置下两个存储的结合是不可能的。Glide提供了另一个用InternalCacheDiskCacheFactory
和ExternalCacheDiskCacheFactory
的方案。就像内存缓存的构造器,磁盘缓存工厂在它们的构造器里接收一个大小的值:
public class CustomCachingGlideModule implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// set size & external vs. internal
int cacheSize100MegaBytes = 104857600;
builder.setDiskCache(
new InternalCacheDiskCacheFactory(context, cacheSize100MegaBytes)
);
//builder.setDiskCache(
//new ExternalCacheDiskCacheFactory(context, cacheSize100MegaBytes));
}
@Override
public void registerComponents(Context context, Glide glide) {
// nothing to do here
}
}
上面的代码会设置磁盘缓存到app的内部路径,并设置最大值到100M。注释斜线后面的那行,会设置磁盘缓存到外部路径(并设置最大值到100M)。
上面的两个方案都不让你选择一个特定的路径。如果你需要移动磁盘缓存到某个特定的位置,你可以利用DiskLruCacheFactory
:
// or any other path
String downloadDirectoryPath = Environment.getDownloadCacheDirectory().getPath();
builder.setDiskCache(
new DiskLruCacheFactory( downloadDirectoryPath, cacheSize100MegaBytes )
);
// In case you want to specify a cache sub folder (i.e. "glidecache"):
//builder.setDiskCache(
// new DiskLruCacheFactory( downloadDirectoryPath, "glidecache", cacheSize100MegaBytes )
//);
使用上面的方案去直接设置一个路径。底部的注释的代码会创建并使用一个在你传递路径里的路径。通常,最后一个参数是byte级缓存的大小。
自定义缓存实现
到目前为止,我们已经展示了如何移动,设置缓存大小。然而,所有调用指向缓存的原始实现。如果你有自己的缓存实现呢?
好吧,你已经知道我们总是创建一个Glide的默认缓存实现实例。你可以创建它的实例并在上面看到的所有方法里传递它来完成你自己的实现。你只要确保你的缓存代码实现了接口方法:
- Memory cache needs to implement: MemoryCache
- Bitmap pool needs to implement BitmapPool
- Disk cache needs to implement: DiskCache
展望
本文中,介绍了如何改变和自定义Glide的缓存。Glide的默认实现组织很好,所以确保你有改变它的原因。如果你要改变一些东西,确保在一定范围的设备上测试!
后面,我们将学习另一个Glide module主题。下篇文章将介绍在大小确定的target ImageView里如何实现一个图片请求,我们保证,将会很棒!