Glide 系列-3:Glide 缓存的实现原理(4.8.0)

本文详细探讨了Glide的缓存实现,包括在GlideModule中配置缓存、内存缓存(LRU和弱引用)以及磁盘缓存的源码分析。内存缓存分为基于LruCache的强引用缓存和弱引用缓存,磁盘缓存使用了策略模式,支持多种缓存策略。通过对Glide缓存机制的理解,有助于优化图片加载性能。

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

1、在 Glide 中配置缓存的方式

首先,我们可以在自定义的 GlideModule 中制定详细的缓存策略。即在 applyOptions() 中通过直接调用 GlideBuilder 的方法来指定缓存的信息:

    @Override
    public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
   
   
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, DISK_CACHE_DIR, DISK_CACHE_SIZE));
        builder.setMemoryCache(...);
        builder.setDiskCache(...);
        // ... 略
    }

另外,我们在每个图片加载请求中自定义当前图片加载请求的缓存策略,

    Glide.with(getContext())
        .load("https://3-im.guokr.com/0lSlGxgGIQkSQVA_Ja0U3Gxo0tPNIxuBCIXElrbkhpEXBAAAagMAAFBO.png")
        .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC))
        .apply(RequestOptions.skipMemoryCacheOf(false))
        .into(getBinding().iv);

以上是两个比较常用的缓存的配置方式,具体的 API 可以查看相关的源码了解.

不论 Glide 还是其他的框架的缓存无非就是基于内存的缓存和基于磁盘的缓存两种,而且缓存的管理算法基本都是 LRU. 针对内存缓存,Android 中提供了 LruCache,笔者在之前的文章中曾经分析过这个框架:

《Android 内存缓存框架 LruCache 的源码分析》

至于磁盘缓存, Glide 和 OkHttp 都是基于 DiskLruCache 进行了封装。这个框架本身的逻辑并不复杂,只是指定了一系列缓存文件的规则,读者可以自行查看源码学习。本文中涉及上述两种框架的地方不再详细追究缓存框架的源码。

2、Glide 缓存的源码分析

2.1 缓存配置

首先, 我们在 applyOptions() 方法中的配置会在实例化单例的 Glide 对象的时候被调用. 所以, 这些方法的作用范围是全局的, 对应于整个 Glide. 下面的方法是 RequestBuilderbuild() 方法, 也就是我们最终完成构建 Glide 的地方. 我们可以在这个方法中了解 RequestBuilder 为我们提供了哪些与缓存相关的方法. 以及默认的缓存配置.

  Glide build(@NonNull Context context) {
   
   
    // ... 无关代码, 略

    if (diskCacheExecutor == null) {
   
   
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }

    if (memorySizeCalculator == null) {
   
   
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }

    if (bitmapPool == null) {
   
   
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
   
   
        bitmapPool = new LruBitmapPool(size);
      } else {
   
   
        bitmapPool = new BitmapPoolAdapter();
      }
    }

    if (arrayPool == null) {
   
   
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    if (memoryCache == null) {
   
    // 默认的缓存配置
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
   
   
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
   
   
      engine = new Engine(/*各种参数*/);
    }

    return new Glide(/*各种方法*/);
  }

这里我们对 MemorySizeCalculator 这个参数进行一些说明. 顾名思义, 它是缓存大小的计算器, 即用来根据当前设备的环境计算可用的缓存空间 (主要针对的时基于内存的缓存).

  MemorySizeCalculator(MemorySizeCalculator.Builder builder) {
   
   
    this.context = builder.context;

    arrayPoolSize =
        isLowMemoryDevice(builder.activityManager)
            ? builder.arrayPoolSizeBytes / LOW_MEMORY_BYTE_ARRAY_POOL_DIVISOR
            : builder.arrayPoolSizeBytes;
    // 计算APP可申请最大使用内存,再乘以乘数因子,内存过低时乘以0.33,一般情况乘以0.4
    int maxSize =
        getMaxSize(
            builder.activityManager, builder.maxSizeMultiplier, builder.lowMemoryMaxSizeMultiplier);

    // ARGB_8888 ,每个像素占用4个字节内存
    // 计算屏幕这么大尺寸的图片占用内存大小
    int screenSize = widthPixels * heightPixels * BYTES_PER_ARGB_8888_PIXEL;
    // 计算目标位图池内存大小
    int targetBitmapPoolSize 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值