Glide学习(二)—缓存策略

本文深入剖析Glide的缓存策略,涵盖内存缓存与硬盘缓存的管理机制,详细解读活动资源与内存资源的区别,以及不同硬盘缓存策略的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在前面一篇文章中,主要分析了Glide的工作流程,以加载网络图片为例分析了Glide是如何工作的。在熟悉了Glide的工作流程后,我们就可以及继续一些细节的分析。接下来,针对Glide的缓存策略进行分析。

我们知道,一个高效的图片框架是少不了缓存的,使用缓存可以减少资源的重复加载,提高资源的利用率。在Glide中,缓存分为两大类:内存缓存以及硬盘缓存。具体到缓存类型可以分为4种,一下是官网给出的缓存类型。

  • 活动资源 (Active Resources) - 现在是否有另一个 View 正在展示这张图片?
  • 内存缓存 (Memory cache) - 该图片是否最近被加载过并仍存在于内存中?
  • 资源类型(Resource) - 该图片是否之前曾被解码、转换并写入过磁盘缓存?
  • 数据来源 (Data) - 构建这个图片的资源是否之前曾被写入过文件缓存?

可以看到,内存缓存分为活动资源以及内存资源;硬盘缓存分为是否有处理过的资源以及原图资源。接下来主要从缓存的更新以及如何缓存两方面分析。

Glide的缓存

缓存键

缓存键是查找的缓存的一个键值,在Glide中需要根据资源的信息构造缓存键,然后查找缓存资源。在分析Glide的工作流程时,在类Engine中开始加载资源时,我们可以看到构造缓存键。

public <R> LoadStatus load(/**省略参数**/) {
    EngineKey key =
        keyFactory.buildKey(
            model,
            signature,
            width,
            height,
            transformations,
            resourceClass,
            transcodeClass,
            options);
}

在Engine的load()方法中可以看到在生成EngineKey的过程中用到了很多参数,比如model资源途径、signature签名、宽高等。这多种参数共同决定了缓存键的生成。

内存缓存

上面说到内存缓存分为活动资源和内存资源(这里先将另外一种资源称为内存资源)。其中活动资源是正在使用的图片也就是正在View中展示的,内存资源是存在内存中的,没有在使用。可以看到,Glide在内存缓存这里将资源又分为了两类。

我继续从Engine的load()方法分析。这里是真正开始加载资源的入口。

public <R> LoadStatus load(/**省略参数**/) {
    long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;

    EngineKey key =
        keyFactory.buildKey(
            model,
            signature,
            width,
            height,
            transformations,
            resourceClass,
            transcodeClass,
            options);

    EngineResource<?> memoryResource;
    synchronized (this) {
      //从内存中加载资源
      memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

      if (memoryResource == null) {
        return waitForExistingOrStartNewJob(/**省略参数**/);
      }
    }
    cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
    return null;
  }

从代码里可以看到Glide先从内存中加载资源,这里调用了loadFromMemory()方法。

private EngineResource<?> loadFromMemory(EngineKey key, boolean isMemoryCacheable, long startTime) {
    //这里是一个配置,使用skipMemoryCache(boolean skip)可以选择是否跳过从缓存中获取资源
    if (!isMemoryCacheable) {
      return null;
    }
    //从活动资源中取缓存
    EngineResource<?> active = loadFromActiveResources(key);
    if (active != null) {
      return active;
    }
    //从内存资源中取缓存
    EngineResource<?> cached = loadFromCache(key);
    if (cached != null) {
      return cached;
    }

    return null;
  }

可以看到,在上面的过程中,Glide是先从活动资源取缓存,如果没有相应的活动资源就从内存资源中取缓存。接着往下看。

private EngineResource<?> loadFromActiveResources(Key key) {
    EngineResource<?> active = activeResources.get(key); //取出活动资源
    if (active != null) {
      active.acquire();
    }
    return active;
  }

在代码可以看到是从activeResources取出的活动资源。我们在这里跟一下这变量可以看到是在Engine的构造函数中进行的初始化。activeResources是ActiveResources类型的变量。我们直接在类ActiveResources看接下来的逻辑。

final class ActiveResources {
    @VisibleForTesting final Map<Key, ResourceWeakReference> ac
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值