Glide源码解析(3)—缓存加载机制

前言

《Glide源码解析(1)—图片加载流程》一文中主要分析了Glide如何从网络下载并设置到ImageView上加载流程。

《Glide源码解析(2)—Glide实例创建过程》一文中主要分析了Glide的创建流程,包括内存缓存和磁盘缓存的初始化。

其中缓存加载机制并没有过多分析,本文就专门分析一下Glide中缓存的加载流程是如何设计的。

设置缓存

Glide.with(this)
    .load("https://url")
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .skipMemoryCache(false)
    .into(iv_glide);

设置内存缓存

  • skipMemoryCache

    是否设置内存缓存。

设置磁盘缓存

  • DiskCacheStrategy.ALL

    缓存SOURCE和RESULT两种图片。

  • DiskCacheStrategy.NONE

    不设置磁盘缓存。

  • DiskCacheStrategy.SOURCE

    缓存SOURCE类型图片,即原图。

  • DiskCacheStrategy.RESULT

    缓存RESULT类型图片,即处理后的图片。

缓存初始化

Glide的缓存可以分为二级缓存也可以分为三级缓存,二级缓存的话就是内存缓存和磁盘缓存,三级缓存的话就是活动内存缓存和非活动内存缓存以及磁盘缓存,缓存的初始化是在Glide实例创建的时候做的,找到GlideBuilder类的createGlide方法,如下所示:

Glide createGlide() {
   
    // 创建资源加载线程池
    if (sourceService == null) {
   
        final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
        sourceService = new FifoPriorityThreadPoolExecutor(cores);
    }
    // 创建磁盘缓存线程池
    if (diskCacheService == null) {
   
        diskCacheService = new FifoPriorityThreadPoolExecutor(1);
    }
	//创建bitmap池
    MemorySizeCalculator calculator = new MemorySizeCalculator(context);
    if (bitmapPool == null) {
   
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   
            int size = calculator.getBitmapPoolSize();
            bitmapPool = new LruBitmapPool(size);
        } else {
   
            bitmapPool = new BitmapPoolAdapter();
        }
    }
	// 创建内存缓存
    if (memoryCache == null) {
   
        memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
    }
	// 创建磁盘缓存
    if (diskCacheFactory == null) {
   
        diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }
	//创建Engine
    if (engine == null) {
   
        engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
    }
	// 设置默认图片格式
    if (decodeFormat == null) {
   
        decodeFormat = DecodeFormat.DEFAULT;
    }
	// 创建Glie实例
    return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}

从源码可以得知内存缓存创建的是LruResourceCache类,磁盘缓存创建的是InternalCacheDiskCacheFactory类。

LruResourceCache类
public class LruResourceCache extends LruCache<Key, Resource<?>> implements MemoryCache {
   
    ......
}

LruResourceCache类继承了AndroidSDK中的LruCache,LRU全称为Least Recently Used,即最近最少使用。

LRU算法就是当缓存空间满了的时候,将最近最少使用的数据从缓存空间中删除,以增加可用的缓存空间来缓存新数据。

这个算法的内部有一个LinkedHashMap类型的缓存列表,每当一个缓存数据被访问的时候,这个数据就会被提到列表尾部,每次都这样的话,列表的头部数据就是最近最不常使用的了,当缓存空间不足时,就会删除列表头部的缓存数据。

InternalCacheDiskCacheFactory类
public final class InternalCacheDiskCacheFactory extends DiskLruCacheFactory {
   
  public InternalCacheDiskCacheFactory(Context context) {
   
        this(context, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR,
             DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
    }
}

从源码可以看到InternalCacheDiskCacheFactory类继承了DiskLruCacheFactory类,并在构造方法中传入了DEFAULT_DISK_CACHE_DIRDEFAULT_DISK_CACHE_SIZE,找到这俩常量:

interface Factory {
   

    /** 250 MB of cache. */
    int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
    String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";

    /**
         * Returns a new disk cache, or {@code null} if no disk cache could be created.
         */
    DiskCache build();
}

可以得知,Glide默认磁盘缓存大小是250M,默认缓存目录名称是image_manager_disk_cacheInternalCacheDiskCacheFactory类继承了DiskLruCacheFactory类,后面再看这个父类。

缓存加载流程

在《Glide源码解析—图片加载流程》一文中,可以得知缓存的加载流程,在Engin类的load方法中:

  public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
            DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
            Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy,
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ruiurrui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值