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方法参数支持 Activity、Fragment、FragmentActivity、View、Context
  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,memoryCache 和 diskCacheFactory 三者都存在时,它们的优先级顺序如下:

  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. 资源加载:
  • 负责从内存缓存、磁盘缓存或网络加载图片资源。 协调 BitmapPool、MemoryCache 和 DiskCache 的使用,确保资源的高效复用。
  1. 缓存管理:
  • 管理内存缓存(MemoryCache)和磁盘缓存(DiskCache),确保资源在合适的时间被缓存和释放。 通过 BitmapPool 复用 Bitmap 对象,减少内存分配和垃圾回收的开销。
  1. 线程池调度:
  • 使用多个线程池(如 sourceExecutor、diskCacheExecutor、animationExecutor)来执行不同的任务,确保图片加载的高效性和流畅性。
  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资源(主线程)

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

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui