2025 再读Android Glide源码

Glide 源码浅析

源码参考: glide 4.15.1版本

基本调用流程跟踪

基本调用链 Glide.with(this).load(url).apply(requestOption).into(imageView)

1. Glide.with(this)

创建Glide实例,创建RequestManager实例,关联RequestManager和context生命周期

  1. Glide提供了多个静态的with重载方法:with方法参数支持 ActivityFragmentFragmentActivityViewContext
  2. with方法会返回一个 RequestManager 对象, 多个with重载方法源码如下
java 复制代码
public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
  }

  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }

  public static RequestManager with(@NonNull Fragment fragment) {
    return getRetriever(fragment.getContext()).get(fragment);
  }

  ...

接下来通过 getRetriever(context) 获取 RequestManagerRetriever实例, RequestManagerRetriever的作用是: 用于创建新的 {@link com.bumptech.glide.RequestManager} 实例,或者从活动(Activity)和片段(Fragment)中获取已存在的实例。 RequestManagerRetriever是在Glide初始化的时候创建的实例

java 复制代码
@NonNull
  private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    // Context could be null for other reasons (ie the user passes in null), but in practice it will
    // only occur due to errors with the Fragment lifecycle.
    Preconditions.checkNotNull(
        context,
        "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
            + "returns null (which usually occurs when getActivity() is called before the Fragment "
            + "is attached or after the Fragment is destroyed).");
    return Glide.get(context).getRequestManagerRetriever();
  }
1.1 Glide实例 通过Glide.get(context)获取,Glide是一个单例

GlideBuilder创建Glide实例源码如下:

java 复制代码
/**
 * 构建Glide单例的核心方法
 * 
 * @param context Android上下文(会自动获取ApplicationContext)
 * @param manifestModules 从AndroidManifest.xml中解析的GlideModule列表
 * @param annotationGeneratedGlideModule 通过@GlideModule注解生成的模块
 * @return 完全初始化的Glide实例
 */
public static Glide build(
      @NonNull Context context,
      List<GlideModule> manifestModules,
      AppGlideModule annotationGeneratedGlideModule) {

    //===== 线程池配置 =====//
    // 源线程池(加载网络/磁盘资源)
    if (sourceExecutor == null) {
        // 默认配置:
        // - 核心线程数 = CPU核心数(至少1,最多4) 内部默认设置最大为4, 如果cpu核心数小于4,则取cpu核心数为核心线程数
        // - 最大线程数 = 核心线程数 = CPU核心数(至少1,最多4)
        // - 线程空闲保持时间 默认是0 设置为 0 表示立即回收空闲线程 因为最大线程数=核心线程数,所以此处不生效
        // - 线程名称前缀 "source-unlimited"
        sourceExecutor = GlideExecutor.newSourceExecutor();
    }

    // 磁盘缓存线程池
    if (diskCacheExecutor == null) {
        // 专用单线程池:
        // - 核心/最大线程数 = 1
        diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }

    // 动画资源加载线程池
    if (animationExecutor == null) {
        // 如果最优线程数>=4, 则最大/核心线程数=2, 否则为1
        animationExecutor = GlideExecutor.newAnimationExecutor();
    }

    //===== 内存计算模块 =====//
    if (memorySizeCalculator == null) {
        memorySizeCalculator = new MemorySizeCalculator.Builder(context)
            // 默认内存计算规则:
            // 总可用内存 = 应用可用内存 * 0.4(默认系数)
            // 位图池大小 = 总可用内存 * 0.3(默认系数)
            // 内存缓存大小 = 总可用内存 * 0.15(默认系数)
            // 数组池大小 = 固定2MB(可通过setArrayPoolSize修改)
            .build();
    }

    //===== 网络监控模块 =====//
    if (connectivityMonitorFactory == null) {
        connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
        // 内部使用ConnectivityManager注册广播接收器
        // 检测网络状态变化时自动恢复/暂停请求
    }

    //===== 缓存池初始化 =====//
    if (bitmapPool == null) {
        int size = memorySizeCalculator.getBitmapPoolSize();
        if (size > 0) {
            // LRU位图池,缓存大小由MemorySizeCalculator计算
            // 默认策略:最近最少使用算法
            bitmapPool = new LruBitmapPool(size);
        } else {
            // 空实现,用于禁用位图池的场景
            bitmapPool = new BitmapPoolAdapter();
        }
    }

    if (arrayPool == null) {
        // 数组缓存池,默认大小4MB(由MemorySizeCalculator计算)
        // 用于复用byte[]、int[]等临时数组,减少GC
        arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    if (memoryCache == null) {
        // 内存缓存,默认使用应用可用内存的15%
        // 缓存条目为Resource对象,包含Bitmap和其他资源
        memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    //===== 磁盘缓存 =====//
    if (diskCacheFactory == null) {
        // 默认使用内部私有目录缓存:
        // 缓存路径:/data/data/<package_name>/image_manager_disk_cache
        // 默认大小250MB(当剩余空间足够时)
        diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    //===== 核心引擎初始化 =====//
    if (engine == null) {
        engine = new Engine(
              memoryCache,               // 内存缓存
              diskCacheFactory,          // 磁盘缓存工厂
              diskCacheExecutor,         // 磁盘缓存线程池
              sourceExecutor,            // 源线程池
              GlideExecutor.newUnlimitedSourceExecutor(), // 无限制线程池(用于预加载)
              animationExecutor,         // 动画线程池
              isActiveResourceRetentionAllowed // 是否保留活动资源标志
        );
        // Engine是Glide的核心调度器,负责:
        // 1. 管理活动资源(正在使用的资源)
        // 2. 协调内存/磁盘缓存
        // 3. 处理线程调度
    }

    //===== 默认请求监听器 =====//
    if (defaultRequestListeners == null) {
        defaultRequestListeners = Collections.emptyList();
    } else {
        // 防止外部修改
        defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

    //===== 实验性功能配置 =====//
    GlideExperiments experiments = glideExperimentsBuilder.build();
    // 包含通过@ExperimentalFeature注解启用的功能

    //===== 请求管理器检索器 =====//
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory, experiments);
    // 负责将RequestManager绑定到生命周期:
    // - Activity/Fragment生命周期感知
    // - 使用无视图Fragment监听生命周期

    //===== 最终构建Glide实例 =====//
    return new Glide(
        context.getApplicationContext(), // 使用应用级上下文防止内存泄漏
        engine,                          // 核心引擎
        memoryCache,                    // 内存缓存
        bitmapPool,                     // 位图池
        arrayPool,                      // 数组池
        requestManagerRetriever,        // 生命周期管理器
        connectivityMonitorFactory,     // 网络状态监控
        logLevel,                       // 日志级别(默认Log.ERROR)
        defaultRequestOptionsFactory,   // 默认请求配置工厂
        defaultTransitionOptions,      // 默认过渡动画配置
        defaultRequestListeners,       // 全局请求监听器
        manifestModules,               // 清单文件模块(兼容旧版)
        annotationGeneratedGlideModule, // 注解生成的配置模块
        experiments                    // 实验性功能
    );
}
1.1.1 线程池配置
  1. 源线程池(加载网络/磁盘资源)最大线程数 = 核心线程数 = CPU核心数(至少1,最多4;
  2. 磁盘缓存线程池,核心/最大线程数 = 1;
  3. 动画线程池,如果glide源线程池>=4, 则最大/核心线程数=2, 否则为1.
  4. Engine中的GlideExecutor.newUnlimitedSourceExecutor(), // 无限制线程池(用于预加载)

1.1.2 缓存池初始化:
  • bitmapPool: 位图池, 默认使用LruBitmapPool(存储在内存中GroupedLinkedMap),缓存大小由MemorySizeCalculator计算
  • memoryCache: 内存缓存, 默认使用LruResourceCache,缓存条目为Resource对象,包含Bitmap和其他资源
  • diskCacheFactory: 磁盘缓存工厂,默认使用InternalCacheDiskCacheFactory,缓存路径:/data/data/<package_name>/image_manager_disk_cache, 默认大小250MB(当剩余空间足够时)
  • arrayPool: 默认使用LruArrayPool,缓存大小为4MB(由MemorySizeCalculator计算) 用于复用byte[]、int[]等临时数组,减少GC

在 Glide 中,当 bitmapPool,memoryCachediskCacheFactory 三者都存在时,它们的优先级顺序如下:

  1. bitmapPool(Bitmap 池)

    • 优先级:最高
    • 原因 :bitmapPool用于复用 Bitmap 对象,避免频繁创建和销毁 Bitmap,从而减少内存分配和垃圾回收的开销。Glide 在加载图片时,会首先尝试从 bitmapPool中获取可复用的 Bitmap 对象。如果找到合适的 Bitmap,则直接复用,否则会创建一个新的 Bitmap
  2. memoryCache(内存缓存)

    • 优先级:次高
    • 原因 :memoryCache 用于缓存已经解码的图片资源(Resource),以便在后续请求中快速获取,而不需要重新解码。当bitmapPool中没有可复用的 Bitmap 时,Glide 会检查 memoryCache中是否已经缓存了该图片。如果缓存命中,则直接使用缓存中的资源;否则,会继续从磁盘缓存或网络加载。
  3. diskCacheFactory(磁盘缓存工厂)

    • 优先级:最低
    • 原因:diskCacheFactory 用于创建磁盘缓存,将图片资源持久化存储在设备的磁盘上,以便在应用重启后仍然可以快速加载。当 bitmapPool 和 memoryCache中都没有找到所需的资源时,Glide 会检查磁盘缓存。如果磁盘缓存中存在该资源,则从磁盘加载;否则,会从网络下载并缓存到磁盘。

总结

  • bitmapPool :优先复用 Bitmap 对象,减少内存分配和垃圾回收。
  • memoryCache:次优先使用内存缓存,加速后续加载。
  • diskCacheFactory:最后使用磁盘缓存,持久化存储图片资源。

这种优先级顺序确保了 Glide 在加载图片时能够最大限度地复用资源,减少网络请求和资源解码的开销,从而优化性能。

疑问点: bitmapPool是缓存位图的, memoryCache缓存的是Resource对象, Resource对象包含了bitmap了,为啥还单独存储了一个bitmappool呢?

  • BitmapPool 专注于 Bitmap 内存复用,避免因频繁创建/销毁 Bitmap 导致以下问题:

    • 内存抖动:频繁触发 GC,导致界面卡顿
    • 分配延迟:Bitmap.createBitmap() 的 CPU 开销
    • 存储未加工的 Bitmap 内存块,可被任何请求复用(只要尺寸匹配)
    java 复制代码
    // 不同URL但相同尺寸的图片,可能复用同一Bitmap内存
    Bitmap bitmap1 = bitmapPool.get(100, 100, ARGB_8888); // URL1
    Bitmap bitmap2 = bitmapPool.get(100, 100, ARGB_8888); // URL2
  • MemoryCache

    • 提供 完整资源的快速访问,避免重复解码、转码、变换等计算:
    java 复制代码
    // MemoryCache 缓存的是"成品"资源
    Resource<Drawable> resource = memoryCache.get(key);
    if (resource != null) {
        target.onResourceReady(resource); // 直接使用缓存
    }
    • 存储特定请求的最终结果(如圆形裁剪后的图片)
    java 复制代码
    // 同一URL但不同变换的图片,需要不同缓存条目
    memoryCache.get(key1); // 原图
    memoryCache.get(key2); // 圆形裁剪后的图

1.1.3 Engine创建

glideEngine创建

java 复制代码
if (engine == null) {
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

Engine 是 Glide 的核心组件之一,负责管理图片加载的生命周期、资源缓存、线程池调度等。它的主要职责包括:

  1. 资源加载:
  • 负责从内存缓存、磁盘缓存或网络加载图片资源。 协调 BitmapPoolMemoryCacheDiskCache 的使用,确保资源的高效复用。
  1. 缓存管理:
  • 管理内存缓存(MemoryCache)和磁盘缓存(DiskCache),确保资源在合适的时间被缓存和释放。 通过 BitmapPool 复用 Bitmap 对象,减少内存分配和垃圾回收的开销。
  1. 线程池调度:
  • 使用多个线程池(如 sourceExecutordiskCacheExecutoranimationExecutor)来执行不同的任务,确保图片加载的高效性和流畅性。
  1. 资源回收:
  • 根据 isActiveResourceRetentionAllowed 参数决定是否允许保留活跃资源,避免资源被过早回收。

第五个参数详解 GlideExecutor.newUnlimitedSourceExecutor()

java 复制代码
public static GlideExecutor newUnlimitedSourceExecutor() {
    return new GlideExecutor(
        new ThreadPoolExecutor(
            0, // 核心线程数(没有常驻线程)
            Integer.MAX_VALUE, // 最大线程数(理论无上限)
            KEEP_ALIVE_TIME_MS,// 线程空闲存活时间(10毫秒)
            TimeUnit.MILLISECONDS,
            new SynchronousQueue<Runnable>(), // 同步移交队列
            new DefaultThreadFactory(
                new DefaultPriorityThreadFactory(),
                DEFAULT_SOURCE_UNLIMITED_EXECUTOR_NAME,
                UncaughtThrowableStrategy.DEFAULT,
                false)));
  }
  • 关键设计:SynchronousQueue + 极短存活时间 队列特性与常规队列对比:

    队列类型 存储能力 任务传递方式 适用场景
    SynchronousQueue 零容量 直接移交(生产者-消费者配对) 需要瞬时创建线程的高吞吐场景
    LinkedBlockingQueue 无界/有界 缓冲任务,先进先出 常规任务队列(需控制并发数)
    PriorityBlockingQueue 无界 按优先级排序 需要任务优先级的场景(如主线程)
  • 行为模式:

    • 没有核心线程,所有任务立即创建新线程执行
    • 线程空闲 10ms 后立即销毁
    • 队列无法存储任务,必须立即移交线程处理

为什么要这样设计?

  1. 专属场景:预加载(Preload)
java 复制代码
  // 使用示例:
  Glide.with(context)
     .load(url)
     .preload(); // 预加载到缓存但不显示
  • 预加载特性:
    • 低优先级:不影响当前可见图片的加载
    • 可丢弃性:即使未完成也不会影响用户体验
    • 数量可控:通常由开发者主动触发,总量有限
  1. 与常规加载的隔离
  • 常规线程池(sourceExecutor):
    • 用于可见图片的即时加载
    • 有严格的核心线程限制(最大为4)
    • 优先级队列保证可见图片优先执行
  • 无限制线程池:
    • 单独处理预加载任务
    • 避免抢占常规线程池资源

这种设计体现了 空间换时间 的优化思想:

  1. 瞬时资源抢占:通过爆发性创建线程快速完成任务
  2. 快速资源释放:利用极短的 KeepAlive 时间及时回收
  3. 场景隔离:与常规加载线程池(SourceExecutor)分离,避免相互影响

1.1.4 Glide实例对象 ,RequestManagerRetriever创建

创建RequestManagerRetriever实例,用于获取RequestManager 创建Glide实例对象

java 复制代码
return new Glide(
        context, // 上下文对象,用于访问应用资源和配置
        engine, // Glide 的核心引擎,负责管理资源加载、缓存和线程池调度
        memoryCache, // 内存缓存,用于缓存已解码的图片资源,加速后续加载
        bitmapPool, // Bitmap 池,用于复用 Bitmap 对象,减少内存分配和垃圾回收
        arrayPool, // 数组池,用于复用临时数组,减少内存分配
        requestManagerRetriever, // 请求管理器检索器,用于获取和管理 RequestManager 实例
        connectivityMonitorFactory, // 网络连接监控工厂,用于监听网络状态变化
        logLevel, // 日志级别,控制 Glide 的日志输出详细程度
        defaultRequestOptionsFactory, // 默认请求选项工厂,用于生成默认的 RequestOptions
        defaultTransitionOptions, // 默认过渡选项,用于定义资源加载完成后的过渡动画
        defaultRequestListeners, // 默认请求监听器列表,用于监听所有请求的生命周期事件
        manifestModules, // 清单模块列表,用于加载 GlideModule 配置
        annotationGeneratedGlideModule, // 注解生成的 GlideModule,用于自定义 Glide 配置
        experiments // 实验性功能配置,用于启用或禁用 Glide 的实验性功能
);
1.2 RequestManager通过getRetriever(fragment.getContext()).get(fragment/activity/FragmentActivity/context/view)获取

在 Glide 中,getRetriever(fragment.getContext()).get(...) 是一个常见的调用方式,用于获取 RequestManager 实例。根据传入的参数类型不同,Glide 会采取不同的策略来管理请求的生命周期。以下是五种情况的详细解释:


1.2.1 get(fragment)

包含两种情况:

  1. fragment是Androidx.fragment
java 复制代码
// 1. RequestManagerRetriever.java
@NonNull
  public RequestManager get(@NonNull Fragment fragment) {
    Preconditions.checkNotNull(
        fragment.getContext(),
        "You cannot start a load on a fragment before it is attached or after it is destroyed");
    if (Util.isOnBackgroundThread()) {
      return get(fragment.getContext().getApplicationContext());
    }
  
    // frameWaiter 的作用是确保 Glide 在合适的时机执行操作,避免在 Activity 或 Fragment 尚未完全初始化时加载图片,从而提升应用的性能和稳定性
    // 此处代码作用是将 Fragment 所属的 Activity 注册到 frameWaiter 中,以便 frameWaiter 可以监听 Activity 的生命周期事件并等待合适的时机执行操作。
    if (fragment.getActivity() != null) {
      frameWaiter.registerSelf(fragment.getActivity());
    }
    FragmentManager fm = fragment.getChildFragmentManager();
    Context context = fragment.getContext();
    Glide glide = Glide.get(context.getApplicationContext());
    return lifecycleRequestManagerRetriever.getOrCreate(
        context, glide, fragment.getLifecycle(), fm, fragment.isVisible());
  }

  // 2. LifecycleRequestManagerRetriever.getOrCreate(...)
  RequestManager getOrCreate(
      Context context,
      Glide glide,
      final Lifecycle lifecycle,
      FragmentManager childFragmentManager,
      boolean isParentVisible) {
    Util.assertMainThread();
    RequestManager result = getOnly(lifecycle);
    if (result == null) {
      LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
      result =
          factory.build(
              glide,
              glideLifecycle,
              new SupportRequestManagerTreeNode(childFragmentManager),
              context);
      lifecycleToRequestManager.put(lifecycle, result);
      glideLifecycle.addListener(
          new LifecycleListener() {
            @Override
            public void onStart() {}

            @Override
            public void onStop() {}

            @Override
            public void onDestroy() {
              lifecycleToRequestManager.remove(lifecycle);
            }
          });
      // This is a bit of hack, we're going to start the RequestManager, but not the
      // corresponding Lifecycle. It's safe to start the RequestManager, but starting the
      // Lifecycle might trigger memory leaks. See b/154405040
      if (isParentVisible) {
        result.onStart();
      }
    }
    return result;
  }
  • 将当前fragment所属的lifecycle和RequestManager进行绑定,通过getOnly(lifecycle),获取指定的Requestmanager, 如果不存在就通过RequestManagerFactory创建RequestManager, 并以fragment的lifecycle为key, RequestManager为value保存到对应的HashMap集合中
  • RequestManagerFactory.build(...)方法中,传入了SupportRequestManagerTreeNode, 此对象用于管理RequestManager树节点, 可以管理所有fragment节点下的RequestManager
  1. fragment是android.app.Fragment
java 复制代码
/**
   * @deprecated Use androidx fragments instead: {@link Fragment}.
   */
  @SuppressWarnings("deprecation")
  @Deprecated
  @NonNull
  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
  public RequestManager get(@NonNull android.app.Fragment fragment) {
    if (fragment.getActivity() == null) {
      throw new IllegalArgumentException(
          "You cannot start a load on a fragment before it is attached");
    }
    if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
      return get(fragment.getActivity().getApplicationContext());
    } else {
  
      if (fragment.getActivity() != null) {
        // frameWaiter 的作用是确保 Glide 在合适的时机执行操作,避免在 Activity 或 Fragment 尚未完全初始化时加载图片,从而提升应用的性能和稳定性
        frameWaiter.registerSelf(fragment.getActivity());
      }
      android.app.FragmentManager fm = fragment.getChildFragmentManager();
      return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
    }
  }

  //---- fragmentGet(...)
  @Deprecated
  @NonNull
  private RequestManager fragmentGet(
      @NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      // TODO(b/27524013): Factor out this Glide.get() call.
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      // This is a bit of hack, we're going to start the RequestManager, but not the
      // corresponding Lifecycle. It's safe to start the RequestManager, but starting the
      // Lifecycle might trigger memory leaks. See b/154405040
      if (isParentVisible) {
        requestManager.onStart();
      }
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

  //---获取一个无界面的RequestManagerFragment
   @SuppressWarnings("deprecation")
  @NonNull
  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
    // If we have a pending Fragment, we need to continue to use the pending Fragment. Otherwise
    // there's a race where an old Fragment could be added and retrieved here before our logic to
    // add our pending Fragment notices. That can then result in both the pending Fragmeng and the
    // old Fragment having requests running for them, which is impossible to safely unwind.
    RequestManagerFragment current = pendingRequestManagerFragments.get(fm);
    if (current == null) {
      current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }
  • 如果在后台或者sdkInt<17 使用全局AplicationContext的RequestManager
  • sdkInt>=17, 会创建一个无界面的RequestManagerFragment, 获取当前fragment的Requestmanager对象,并和Requestmanager绑定其生命周期
1.2.2 get(activity)
java 复制代码
@Deprecated
  @SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else if (activity instanceof FragmentActivity) {
      return get((FragmentActivity) activity);
    } else {
      assertNotDestroyed(activity);
      frameWaiter.registerSelf(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(activity, fm, /* parentHint= */ null, isActivityVisible(activity));
    }
  }
  • 是否在后台, 如果是 则使用全局AplicationContext的RequestManager
  • 是否是FragmentActivity, 如果是则使用FragmentActivity的RequestManager
  • 否则, 创建一个无界面的RequestManagerFragment, 获取当前activity的Requestmanager对象,并和Requestmanager绑定其生命周期
1.2.3 get(FragmentActivity)
java 复制代码
@NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    }
    assertNotDestroyed(activity);
    frameWaiter.registerSelf(activity);
    boolean isActivityVisible = isActivityVisible(activity);
    Glide glide = Glide.get(activity.getApplicationContext());
    return lifecycleRequestManagerRetriever.getOrCreate(
        activity,
        glide,
        activity.getLifecycle(),
        activity.getSupportFragmentManager(),
        isActivityVisible);
  }
  • 获取/创建当前FragmentActivity的Requestmanager对象,并和Lifecycle绑定生命周期
1.2.4 get(view)
java 复制代码
@SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull View view) {
    if (Util.isOnBackgroundThread()) {
      return get(view.getContext().getApplicationContext());
    }

    Preconditions.checkNotNull(view);
    Preconditions.checkNotNull(
        view.getContext(), "Unable to obtain a request manager for a view without a Context");
    Activity activity = findActivity(view.getContext());
    // The view might be somewhere else, like a service.
    if (activity == null) {
      return get(view.getContext().getApplicationContext());
    }

    // 
    if (activity instanceof FragmentActivity) {
      Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
      return fragment != null ? get(fragment) : get((FragmentActivity) activity);
    }

    // Standard Fragments.
    android.app.Fragment fragment = findFragment(view, activity);
    if (fragment == null) {
      return get(activity);
    }
    return get(fragment);
  }
  • 获取view挂载的activity, 如果是FragmentActivity, 则使用FragmentActivity的RequestManager
  • 否则, 获取view对应的fragment, 如果有则使用fragment的RequestManager, 否则使用activity的RequestManager
1.2.5 get(context)
  • 获取全局AplicationContext的RequestManager
1.3 总结

Glide.with()方法的作用是:

  1. 创建单例的Glide对象, 并且配置了线程池,缓存池, Engine, RequestManager追踪器RequestManagerRetriever
  2. 绑定RequestManager和 1.AndroidX版本是当前activity/fragment的生命周期 2.非AndroidX版本是创建了一个不可视的RequestManagerFragment的生命周期

2. load()方法

load方法同样的也是有多个重载方法

java 复制代码
  public GlideRequest<Drawable> load(@Nullable Bitmap bitmap) {
    return (GlideRequest<Drawable>) super.load(bitmap);
  }

  public GlideRequest<Drawable> load(@Nullable Drawable drawable) {
    return (GlideRequest<Drawable>) super.load(drawable);
  }

  public GlideRequest<Drawable> load(@Nullable String string) {
    return (GlideRequest<Drawable>) super.load(string);
  }

  public GlideRequest<Drawable> load(@Nullable Uri uri) {
    return (GlideRequest<Drawable>) super.load(uri);
  }

  public GlideRequest<Drawable> load(@Nullable File file) {
    return (GlideRequest<Drawable>) super.load(file);
  }

  public GlideRequest<Drawable> load(@RawRes @DrawableRes @Nullable Integer id) {
    return (GlideRequest<Drawable>) super.load(id);
  }

  public GlideRequest<Drawable> load(@Nullable URL url) {
    return (GlideRequest<Drawable>) super.load(url);
  }

  public GlideRequest<Drawable> load(@Nullable byte[] bytes) {
    return (GlideRequest<Drawable>) super.load(bytes);
  }

  public GlideRequest<Drawable> load(@Nullable Object o) {
    return (GlideRequest<Drawable>) super.load(o);
  }

返回对象均为 RequestBuilder的子类,并且全部转为了GlideRequest <Drawable>, 以上目的是将加载参数放入requestBuilder中, 后续into会调用RequestBuilder的buildRequest方法将load的参数用于创建Request对象

3. into()方法

3.1 into(imageView)方法
java 复制代码
@NonNull
  public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    Util.assertMainThread();
    Preconditions.checkNotNull(view);

  
    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {

      switch (view.getScaleType()) {
        case CENTER_CROP:
          requestOptions = requestOptions.clone().optionalCenterCrop();
          break;
        case CENTER_INSIDE:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case FIT_CENTER:
        case FIT_START:
        case FIT_END:
          requestOptions = requestOptions.clone().optionalFitCenter();
          break;
        case FIT_XY:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case CENTER:
        case MATRIX:
        default:
          // Do nothing.
      }
    }

    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /* targetListener= */ null,
        requestOptions,
        Executors.mainThreadExecutor());
  }
    1. 获取图片展示配置赋值给 requestOptions
    1. 调用into(tartget, targetListener, requestOptions, callbackExecutor) 方法
3.1.1 四个参数解析
  1. glideContext.buildImageViewTarget(view, transcodeClass)
java 复制代码
// GlideContext.java
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
      @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
    return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
  }

// ImageViewTargetFactory
public <Z> ViewTarget<ImageView, Z> buildTarget(
      @NonNull ImageView view, @NonNull Class<Z> clazz) {
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
  }
  • 第一个参数. 从load方法中最终全部转为了GlideRequest <Drawable>,也就是默认情况下 transcodeClass = Drawable; 所以默认会得到DrawableImageViewTarget, 调用了asBitmap()方法后会得到transcodeClass = BitmapImageViewTarget
  • 第二个参数: 默认为null
  • 第三个参数: imageView配置
  • 第四个参数: 回调线程设置会主线程
3.2 into(tartget, targetListener, requestOptions, callbackExecutor)方法

RequstBuilder类内部into方法内通过buildRequest创建Request对象, 通过Engine管理请求/线程池/缓存池的调度, 如果未命中缓存,最终再发起请求

java 复制代码
private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    Preconditions.checkNotNull(target);
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

    // 创建request
    Request request = buildRequest(target, targetListener, options, callbackExecutor);

    // 请求复用检查,获取目标上已有的请求(可能正在进行或已完成)
    Request previous = target.getRequest();
    // 判断新旧请求是否等效(相同URL、相同配置等)
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
          // 若旧请求未在运行中,则重新开始(触发回调)
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        // (1) 重新启动请求但复用已有资源
        previous.begin();
      }
      // 请求正在执行,直接返回避免重复请求
      return target;
    }
    //===== 新请求处理流程 =====//
    // 清理目标上关联的旧请求
    requestManager.clear(target);
    // 将新请求绑定到目标
    target.setRequest(request);
    // (2) 跟踪并启动新请求
    requestManager.track(target, request);

    return target;
  }
  1. 创建request
  2. 复用检查,获取目标上已有请求 如果新旧请求等效,判断请求是否在执行中, 如果正在执行,直接返回避免重复请求; 否则重启请求,复用已有资源
  3. 新请求开始,请求target绑定, 关联新的Request, 跟踪并启动新请求
3.2.1 (1)处: previous.begin()
java 复制代码
  
// SingleRequest.java
@Override
  public void begin() {
    synchronized (requestLock) {
      assertNotCallingCallbacks();
      stateVerifier.throwIfRecycled();
      startTime = LogTime.getLogTime();
      // model 是load(model)进来的对象, 不能为null
      if (model == null) {
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
          width = overrideWidth;
          height = overrideHeight;
        }
        int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
        onLoadFailed(new GlideException("Received null model"), logLevel);
        return;
      }

      // 状态进行中 说明前面拦截失败 直接报错
      if (status == Status.RUNNING) {
        throw new IllegalArgumentException("Cannot restart a running request");
      }

      // 状态已完成回调
      if (status == Status.COMPLETE) {
        onResourceReady(
            resource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
        return;
      }

      // 通知请求开始的事件给监听器
      experimentalNotifyRequestStarted(model);

      cookie = GlideTrace.beginSectionAsync(TAG);
      status = Status.WAITING_FOR_SIZE;
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        // 资源准备就绪 执行复用/请求 逻辑
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        // 异步获取size
        target.getSize(this);
      }

      if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
          && canNotifyStatusChanged()) {
        target.onLoadStarted(getPlaceholderDrawable());
      }
      if (IS_VERBOSE_LOGGABLE) {
        logV("finished run method in " + LogTime.getElapsedMillis(startTime));
      }
    }
  }

  /** A callback method that should never be invoked directly. */
  // 应为是begin是资源复用阶段, 如果已存在则无需再等待size准备阶段,可以直接调用
  @Override
  public void onSizeReady(int width, int height) {
    stateVerifier.throwIfRecycled();
    synchronized (requestLock) {
      if (IS_VERBOSE_LOGGABLE) {
        logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
      }
      if (status != Status.WAITING_FOR_SIZE) {
        return;
      }
      status = Status.RUNNING;

      float sizeMultiplier = requestOptions.getSizeMultiplier();
      this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
      this.height = maybeApplySizeMultiplier(height, sizeMultiplier);

      if (IS_VERBOSE_LOGGABLE) {
        logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
      }
      loadStatus =
          engine.load(
              glideContext,
              model,
              requestOptions.getSignature(),
              this.width,
              this.height,
              requestOptions.getResourceClass(),
              transcodeClass,
              priority,
              requestOptions.getDiskCacheStrategy(),
              requestOptions.getTransformations(),
              requestOptions.isTransformationRequired(),
              requestOptions.isScaleOnlyOrNoTransform(),
              requestOptions.getOptions(),
              requestOptions.isMemoryCacheable(),
              requestOptions.getUseUnlimitedSourceGeneratorsPool(),
              requestOptions.getUseAnimationPool(),
              requestOptions.getOnlyRetrieveFromCache(),
              this,
              callbackExecutor);

  
      if (status != Status.RUNNING) {
        loadStatus = null;
      }
      if (IS_VERBOSE_LOGGABLE) {
        logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
      }
    }
  }
  • begin 判断资源是否准备完成, 如果已准备完成进入 onSizeReady阶段,否则getSize异步获取尺寸 → 触发 onSizeReady()
  • onSizeReady中 设置状态为Status.RUNNING, 执行engine.load()
java 复制代码
begin()
  ├─ onSizeReady() // 尺寸就绪
  │   └─ engine.load() // 进入引擎加载
  │       ├─ 检查活动资源
  │       ├─ 检查内存缓存
  │       ├─ 检查磁盘缓存
  │       └─ 发起网络请求(如需要)
  └─ target.getSize() → 异步获取尺寸 → 触发 onSizeReady()

engine.load()详解

java 复制代码
/**
 * Glide引擎加载资源的核心方法,负责协调内存缓存、磁盘缓存和资源生成
 * 
 * @param <R> 转码后的资源类型(如Drawable)
 * @param glideContext Glide上下文,包含注册组件
 * @param model 数据源标识(如URL/File/Uri)
 * @param signature 唯一签名(用于缓存版本控制)
 * @param width 目标宽度
 * @param height 目标高度
 * @param resourceClass 原始资源类型(如Bitmap)
 * @param transcodeClass 目标转码类型(如Drawable)
 * @param priority 请求优先级
 * @param diskCacheStrategy 磁盘缓存策略
 * @param transformations 变换操作集合
 * @param isTransformationRequired 是否必须应用变换
 * @param options 解码选项
 * @param isMemoryCacheable 是否启用内存缓存
 * @param cb 资源回调接口
 * @param callbackExecutor 回调执行器(主线程)
 * @return LoadStatus 用于跟踪或取消加载
 */
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) {
      // 1. 检查内存缓存(活动资源+LRU缓存)
      memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

      if (memoryResource == null) {
        // 2. 缓存未命中,进入异步加载流程
        return waitForExistingOrStartNewJob(...);
      }
    }

    // 3. 命中缓存 回调缓存资源
    cb.onResourceReady(
        memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
    return null;
  }

  // 缓存检查代码
  EngineResource<?> loadFromMemory(EngineKey key, boolean isMemoryCacheable, long startTime) {
    // 检查活动资源(正在使用的资源)
    EngineResource<?> active = loadActiveResources(key);
    if (active != null) return active;

    // 检查LRU内存缓存(需isMemoryCacheable=true)
    EngineResource<?> cached = loadFromCache(key);
    if (cached != null) {
        // 移入活动资源
        activeResources.activate(key, cached);
        return cached;
    }

    return null;
}
  1. 获取缓存资源, 如果命中了 则直接进入(3) 回调资源
  2. 如果缓存未命中 执行异步加载流程(2)waitForExistingOrStartNewJob, 源码分析如下
java 复制代码
//主要参数说明
 /* 
 * @param key 唯一标识请求的复合键(包含尺寸、变换、数据源等参数)
 * @param onlyRetrieveFromCache 是否仅从缓存加载(不发起网络请求)
 * @param cb 资源回调接口,用于接收加载结果
 * @param callbackExecutor 回调执行器(通常是主线程的 MainThreadExecutor)
 */ 
private <R> LoadStatus waitForExistingOrStartNewJob(...) {
    //  检查任务
    EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
    if (current != null) {
      // 复用现有任务
      current.addCallback(cb, callbackExecutor);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Added to existing load", startTime, key);
      }
      return new LoadStatus(cb, current);
    }
  
    // 创建新任务 管理任务状态、处理线程调度、协调多个回调。
    EngineJob<R> engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);

    // 执行实际的资源加载、解码、转码流程
    DecodeJob<R> decodeJob =
        decodeJobFactory.build(...);
    // 加入全局任务表, 供后续请求复用
    jobs.put(key, engineJob);
  
    // (1) 添加资源结果回调,并将每个回调添加到cbs(全局列表中),以便于decodeJob资源完成之后,遍历cbs再次执行回调
    engineJob.addCallback(cb, callbackExecutor);
    // (2) 内部将 DecodeJob 提交到适当线程池:
    // - 磁盘缓存:GlideExecutor (diskCacheExecutor)
    // - 网络请求:GlideExecutor (sourceExecutor)
    // - 动画: GlideExecutor(animationExecutor)
    engineJob.start(decodeJob);

    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Started new load", startTime, key);
    }
    return new LoadStatus(cb, engineJob);
  }
  • (1)处 将cb(ResourceCallback) 存储到全局的cbs内, 编于decode完成后 遍历所有cbs并回调
    • 回调添加时资源已就绪 → 立即提交到主线程队列(但非立即执行)
    • 回调添加时资源未就绪 → 暂存回调,待后续解码完成后再触发
java 复制代码
synchronized void addCallback(final ResourceCallback cb, Executor callbackExecutor) {
    stateVerifier.throwIfRecycled();
    // 存储到EngineJob的cbs中, EngineJob在初始化Engin时创建,所以是全局的
    cbs.add(cb, callbackExecutor);
    // 如果已有资源,则将任务加入到主线程的MessageQueue,待Looper处理到时执行run方法, decode成功后会执行到EngineJob的onResourceReady方法内,hasResource在这里设置为true,
    if (hasResource) {
      incrementPendingCallbacks(1);
      callbackExecutor.execute(new CallResourceReady(cb));
    } else if (hasLoadFailed) {
      incrementPendingCallbacks(1);
      callbackExecutor.execute(new CallLoadFailed(cb));
    } else {
      Preconditions.checkArgument(!isCancelled, "Cannot add callbacks to a cancelled EngineJob");
    }
  }
  • (2)处 将DecodeJob放到对应的线程池中执行,下面是对应的判断使用对应线程池的具体代码 DecodeJob 是 Glide 图片加载框架中的核心工作单元,负责协调 数据获取、解码、转码、缓存 等关键流程。它的作用可以概括为:将原始数据源(如 URL、File 等)转换为目标可用的资源(如 Bitmap、Drawable),同时遵循 Glide 的缓存策略和线程模型。
java 复制代码
// EngineJob.java
 public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor =
        decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }
private GlideExecutor getActiveSourceExecutor() {
    return useUnlimitedSourceGeneratorPool
        ? sourceUnlimitedExecutor
        : (useAnimationPool ? animationExecutor : sourceExecutor);
  }

DecodeJob.java 的核心代码注释如下: 该实现通过状态机和责任链模式,将复杂的解码流程分解为可管理的阶段,既保证了各环节的独立性,又通过统一的异常处理机制确保了系统稳定性。

java 复制代码
/**
 * DecodeJob的核心执行方法,运行在指定的线程池中(如磁盘缓存线程或源线程)
 * 职责:协调整个解码流程,处理异常,确保资源清理
 */
@Override
public void run() {
    // 开始性能跟踪区块(用于Debug时查看方法耗时)
    GlideTrace.beginSectionFormat("DecodeJob#run(reason=%s, model=%s)", runReason, model);
  
    // 使用局部变量持有当前数据抓取器,确保finally块中能正确清理
    DataFetcher<?> localFetcher = currentFetcher;
  
    try {
        // 检查任务是否已被取消
        if (isCancelled) {
            notifyFailed(); // 通知失败回调
            return;
        }
        runWrapped(); // 进入核心处理流程
    } catch (CallbackException e) {
        // 透传非Glide控制的回调异常(通常由用户代码引起)
        throw e; 
    } catch (Throwable t) { // 捕获所有异常包括Error(如OOM)
        // 调试日志记录
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG,"DecodeJob threw unexpectedly, isCancelled: "+isCancelled+", stage: "+stage, t);
        }
    
        // 非编码阶段收集异常并通知失败
        if (stage != Stage.ENCODE) {
            throwables.add(t);
            notifyFailed(); 
        }
    
        // 如果未被显式取消,重新抛出异常
        if (!isCancelled) throw t; 
        throw t; // 已取消的请求仍抛出但会被EngineJob忽略
    } finally {
        // 清理数据抓取器资源(如关闭网络连接)
        if (localFetcher != null) {
            localFetcher.cleanup(); 
        }
        GlideTrace.endSection(); // 结束性能跟踪
    }
}

/**
 * 根据当前运行原因(RunReason)执行对应的处理阶段
 */
private void runWrapped() {
    switch (runReason) {
        case INITIALIZE: // 初始运行(首次进入或重试)
            // 确定下一个处理阶段(资源缓存->数据缓存->源数据)
            stage = getNextStage(Stage.INITIALIZE); 
            // 获取对应阶段的生成器(如ResourceCacheGenerator)
            currentGenerator = getNextGenerator(); 
            runGenerators(); // 启动生成器执行
            break;
        case SWITCH_TO_SOURCE_SERVICE: // 切换到源数据服务
            runGenerators(); // 继续执行生成器(通常已切换至SourceGenerator)
            break;
        case DECODE_DATA: // 数据就绪,进行解码
            decodeFromRetrievedData(); // 执行解码流程
            break;
        default:
            throw new IllegalStateException("Unrecognized run reason: " + runReason);
    }
}
3.2.2 (2)处: requestManager.track(target, request)
java 复制代码
// RequestManager.java
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    // 跟踪目标对象
    targetTracker.track(target);
    // 管理加载请求
    requestTracker.runRequest(request);
  }

// RequestTracker.java
public void runRequest(@NonNull Request request) {
    requests.add(request);          // 步骤1:记录所有请求
    if (!isPaused) {                // 步骤2:检查暂停状态
        request.begin();            // 步骤2a:未暂停,立即启动
    } else {                    
        request.clear();            // 步骤2b:已暂停,取消请求
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "Paused, delaying request");
        }
        pendingRequests.add(request); // 步骤3:加入待定队列
    }
}

  // TargetTracker类(简略)
public class TargetTracker {
    private final Set<Target<?>> targets = Collections.newSetFromMap(new WeakHashMap<>());

    public void track(@NonNull Target<?> target) {
        targets.add(target); // 使用WeakHashMap防止内存泄漏
    }
}

track的作用

  • 使用弱引用集合存储 Target,当外部(如 Activity)销毁时,Target 可被自动回收。
  • 页面销毁时,TargetTracker 可自动清除所有跟踪的 Target,终止关联的请求。

requests集合的作用

  • 全局管理所有活跃请求(无论是否暂停),用于批量操作(如暂停时取消所有请求)。
  • isPaused 字段来源: 通过 RequestTracker 的 pauseRequests()/resumeRequests() 方法设置。常见触发场景:

设计原理总结

  1. 生命周期整合 场景:当应用进入后台 (onStop),暂停所有请求以避免不必要的 CPU/网络消耗。 恢复机制:返回前台时 (onStart),从 pendingRequests 重启请求,确保界面自动刷新。
  2. 内存安全 弱引用追踪:TargetTracker 使用弱引用集合,避免因 Target 未释放导致的内存泄漏。 资源回收:请求暂停时,request.clear() 及时释放资源(如 Bitmap 的引用)。
  3. 线程安全 同步控制:synchronized 块确保并发环境下,请求的添加和状态判断是原子的。 数据结构选择:requests 和 pendingRequests 通常使用线程安全集合(如 ConcurrentLinkedQueue)。

调用流程总结

  1. with方法的作用是: (如果是第一次调用)创建Glide对象, 初始化线程池、缓存池、Engine(线程池和缓存池调度的 协调解码,转码和回调任务)、RequestManager(并关联生命周期)
  2. 后续的RequestManager里的load,apply方法的作用是将加载参数放入RequestBuilder中,后续供into中使用
  3. into方法的作用是:
  • into参数最终都变化为DrawableImageViewTarget或BitmapImageViewTarget
  • into方法内通过RequstBuilder的buildRequest创建Request对象
  • Request作用是缓存请求,并和Target进行关联
  • RequestManager: track追踪请求,协调Request和Target, 在适当的时机释放资源
  • Glide引擎加载资源的核心方法engine.load(),负责协调内存缓存、磁盘缓存和资源生成
  • 如果缓存未命中:
    *
    1. 创建新任务(EnginJob) 管理任务状态、处理线程调度、协调多个回调
      1. 创建DecodeJob(资源加载/解码转码任务):负责协调 数据获取、解码、转码、缓存 等关键流程。它的作用可以概括为:将原始数据源(如 URL、File 等)转换为目标可用的资源(如 Bitmap、Drawable)
      1. 通过cb(ResourseCallback)回调resource资源(主线程)

目前作者在魔都求职中, 希望被各位大佬推荐谢谢

相关推荐
CYRUS_STUDIO1 小时前
深入 Android syscall 实现:内联汇编系统调用 + NDK 汇编构建
android·操作系统·汇编语言
死也不注释3 小时前
【第一章编辑器开发基础第一节绘制编辑器元素_6滑动条控件(6/7)】
android·编辑器
程序员JerrySUN4 小时前
Linux 文件系统实现层详解:原理、结构与驱动衔接
android·linux·运维·数据库·redis·嵌入式硬件
2501_916013744 小时前
iOS 加固工具使用经验与 App 安全交付流程的实战分享
android·ios·小程序·https·uni-app·iphone·webview
南棱笑笑生5 小时前
20250715给荣品RD-RK3588开发板刷Android14时打开USB鼠标
android·计算机外设
hy.z_7776 小时前
【数据结构】反射、枚举 和 lambda表达式
android·java·数据结构
幻雨様6 小时前
UE5多人MOBA+GAS 20、添加眩晕
android·ue5
没有了遇见7 小时前
开源库 XPopup 资源 ID 异常修复:从发现 BUG 到本地 AAR 部署全流程
android
雮尘7 小时前
一文读懂 Android 屏幕适配:从基础到实践
android·前端
用户2018792831677 小时前
浅谈焦点冲突导致异常背景色的机制
android