Glide中的缓存(基于3.7版本)

这个是面试可能会问到的glide缓存机制

glide的缓存策略有两种,即内存缓存和磁盘缓存.首先提一点就是glide默认图片格式是RGB_565.

1.内存缓存(LruResourceCache)

Glide默认是会在内存中缓存处理图(RESULT)的.
可以通过调用skipMemoryCache(true)来设置跳过内存缓存

Glide.with(this).load(mUrl).skipMemoryCache(true).into(mIv);
//MemorySizeCalculator.java

final int maxSize = getMaxSize(activityManager);

private static int getMaxSize(ActivityManager activityManager) {
    //每个进程可用的最大内存
    final int memoryClassBytes = activityManager.getMemoryClass() * 1024 * 1024;

    //判断是否低配手机
    final boolean isLowMemoryDevice = isLowMemoryDevice(activityManager);

    return Math.round(memoryClassBytes
            * (isLowMemoryDevice ? LOW_MEMORY_MAX_SIZE_MULTIPLIER : MAX_SIZE_MULTIPLIER));
}
根据源码知道,最大内存:如果是低配手机,就每个进程可用的最大内存乘以0.33,否则就每个进程可用的最大内存乘以0.4

使用内存缓存可以获得更快的图片加载速度,因为减少了耗时的IO操作.Glide中有一个叫做BitmapPool的类,可以复用其中的Bitmap对象,从而避免Bitmap对象的创建,减小内存开销。当配置内存缓存时,我们也可以同时配置BitmapPool的大小。

builder.setMemoryCache(new LruResourceCache(yourSizeInBytes));
builder.setBitmapPool(new LruBitmapPool(sizeInBytes));

当然也可以不自己设置,因为glide已经帮我们设置好了.默认的内存缓存和bitmapPool的大小由MemorySizeCalculator根据当前设备的屏幕大小和可用内存计算得到.

//MemorySizeCalculator.java

int screenSize = screenDimensions.getWidthPixels() * screenDimensions.getHeightPixels()
                * BYTES_PER_ARGB_8888_PIXEL;(**4)
int targetPoolSize = screenSize * BITMAP_POOL_TARGET_SCREENS;(**4*4)
int targetMemoryCacheSize = screenSize * MEMORY_CACHE_TARGET_SCREENS;(**4*2)

//判断是否超过最大值,否则就等比缩小
if (targetMemoryCacheSize + targetPoolSize <= maxSize) {
    memoryCacheSize = targetMemoryCacheSize;
    bitmapPoolSize = targetPoolSize;
} else {
    int part = Math.round((float) maxSize / (BITMAP_POOL_TARGET_SCREENS + MEMORY_CACHE_TARGET_SCREENS));
    memoryCacheSize = part * MEMORY_CACHE_TARGET_SCREENS;
    bitmapPoolSize = part * BITMAP_POOL_TARGET_SCREENS;
}
根据源码知道,内存缓存用的是targetMemoryCacheSize (即一般是缓存大小是屏幕的宽 * 高 * 4 * 2),图片池用的是targetPoolSize(即一般是缓存大小是屏幕的宽4*4).

Glide还支持动态的缓存大小调整,在存在大量图片的Activity/Fragment中,可以通过setMemoryCategory方法来提高Glide的内存缓存大小,从而加快图片的加载速度。

Glide.get(context).setMemoryCategory(MemoryCategory.HIGH);

MemoryCategory有3个值可供选择:
1.MemoryCategory.HIGH(初始缓存大小的1.5倍)
2.MemoryCategory.NORMAL(初始缓存大小的1倍)
3.MemoryCategory.LOW(初始缓存大小的0.5倍)

2.磁盘缓存(DiskLruCacheFactory)

Glide在默认情况下是开启磁盘缓存的.
Glide磁盘缓存策略分为四种,默认的是RESULT:
1.ALL:缓存原图和处理图
2.NONE:什么都不缓存
3.SOURCE:只缓存原图
4.RESULT:只缓存处理图

//DiskCache.java

/** 250 MB of cache. */
        int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
        String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
源码得知:默认大小:250 MB,默认目录:image_manager_disk_cache.

开发者可以通过构建一个自定义的GlideModule来配置Glide磁盘缓存的位置和大小.

public class DiskCacheMoudle implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        builder.setDiskCache(
                new InternalCacheDiskCacheFactory(context, "cache", 1000 * 1024 * 1024));
        //builder.setDiskCache(
        //        new ExternalCacheDiskCacheFactory(context, "cache", 1000 * 1024 * 1024));
    }

    @Override
    public void registerComponents(Context context, Glide glide) {

    }
}

其中InternalCache和ExternalCache都最多接收3个参数:第一个参数为Context;第二个为缓存的目录名称;第三个为缓存大小,单位是Byte。InternalCache构建的缓存是在应用的内部储存,而ExternalCache则是在外部储存。
内部储存中的缓存文件是其他应用程序是无法获取到的,更加安全。

在Glide中磁盘缓存默认使用的是LRU(Least Recently Used)算法。如果你想使用其他的缓存算法,就只能通过实现DiskCache接口来完成了。

LRU算法:

1.LruCache 是基于 Lru算法实现的一种缓存机制;
2.Lru算法的原理是把近期最少使用的数据给移除掉,当然前提是当前数据的量大于设定的最大值。
3.LruCache 没有真正的释放内存,只是从 Map中移除掉数据,真正释放内存还是要用户手动释放。

清除缓存,在使用中的资源不会被清除

1.清除所有内存缓存(需要在Ui线程操作)

Glide.get(this).clearMemory();

2.清除所有磁盘缓存(需要在子线程操作)

Glide.get(MainActivity.this).clearDiskCache();
由于Glide可能会缓存一张图片的多个分辨率的图片,并且文件名是被哈希过的,所以并不能很好的删除单个资源的缓存.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值