Glide入门教程(16)自定义缓存

自定义内存缓存

       自定义Glide,我们需要创建一个Glide module。在前面的文章中介绍过,applyOptions方法提供了访问GlideBuilder对象的方法。GlideBuilder方法提供了几个方法去自定义Glide的缓存。首先看看内存缓存。

       内存缓存是在设备的RAM中保存图片。由于没有IO操作,所以非常快。不利的是RAM的大小是受到限制的。在小内存缓存和大内存缓存之间找到一个合适的平衡点并不简单。Glide内存使用MemorySizeCalculator类去决定内存缓存和bitmap池的大小。Bitmap池保存着在你的应用heap里放着的图片。Bitmap池的正确大小是很重要的,它可以防止过多地重新分配图片,可以让垃圾回收器的生命更简单。

       Glide的MemorySizeCalculator类和默认的计算:

1
2
3
MemorySizeCalculator calculator = new MemorySizeCalculator(context);  
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();

       如果你想要使用默认值作为基线并调整,上面的代码是非常有用的。例如,你想要你的app比默认多20%的缓存,使用上面的变量来计算它们:

1
2
int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);  
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);

       由于已经指出我们的内存缓存和Bitmap池的大小,我们可以编码Glide module。在applyOption()方法中,可以在GlideBuilder对象上调用合适的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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的方案。就像内存缓存的构造器,磁盘缓存工厂在它们的构造器里接收一个大小的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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:

1
2
3
4
5
6
7
8
9
10
11
// 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入门教程——18.Glide Module案例: 自定义缓存

Fork me on GitHub