Glide with(xxx)源码分析

作者: zl_adams | 来源:发表于2020-04-11 19:37 被阅读0次

Glide的使用不需要显式的去初始化框架,其内部实现好了初始化。并且实现了图片加载的启动和结束与页面的生命周期绑定在一起。
本篇文章源码分析基于Glide4.9.0

Glide图片加载的基本使用:

Glide.with(this).load(url).into(imageView);
1、先从with()方法入手查看
public class Glide implements ComponentCallbacks2 {

  @NonNull
  public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
  }

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

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

  @NonNull
  public static RequestManager with(@NonNull android.support.v4.app.Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
  }

  @SuppressWarnings("deprecation")
  @Deprecated
  @NonNull
  public static RequestManager with(@NonNull android.app.Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
  }

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




-->调用getRetriever()获取RequestManagerRetriever
  @NonNull
  private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    //先检查context是否为空
    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();//先调用Glide.get(context),往下看2、Glide开始初始化
  }

  -->直接返回requestManagerRetriever变量
  @NonNull
  public RequestManagerRetriever getRequestManagerRetriever() {
    return requestManagerRetriever;
  }

}
  • 首先with()方法的返回参数是RequestManager,with方法的目的就是需要获取RequestManager类,因为通过RequestManager类才能调用load()方法加载图片;
  • with()方法内部首先调用了getRetriever方法。
  • getRetriever方法执行了Glide.get(context).getRequestManagerRetriever(),其实先调用Glide.get(context)获取Glide的实例,然后调用getRequestManagerRetriever()返回Glide内部的RequestManagerRetriever实例。
  • 往下查看Glide.get(context)的过程。
2、Glide初始化入口
  //单例设计模式
  @NonNull
  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context);
        }
      }
    }

    return glide;
  }


  -->加上判断,防止多次初始化
  private static void checkAndInitializeGlide(@NonNull Context context) {
    // In the thread running initGlide(), one or more classes may call Glide.get(context).
    // Without this check, those calls could trigger infinite recursion.
    if (isInitializing) {
      throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
          + " use the provided Glide instance instead");
    }
    isInitializing = true;//设置正在初始化标志位true
    initializeGlide(context);
    isInitializing = false;
  }

  -->
  //创建GlideBuilder(GlideBuilder是Glide的配置文件,如缓存配置,线程池配置),
  //往下调用initializeGlide的重载方法
  private static void initializeGlide(@NonNull Context context) {
    initializeGlide(context, new GlideBuilder());
  }

单例设计模式和isInitializing标记变量确保Glide是全局单例。

3、创建Glide的实例
  //配置GlideBuilder,并实例化Glide
  private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    //获取AppGlideModule的实例,用于提供扩展 Glide 的 API;
    //获取Application 模块中AppGlideModule的实现,比如public final class MyAppGlideModule extends AppGlideModule {}
    GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      // 解析AndroidManifest中自定义的GlideModule的metadata标签,返回一个GlideModule集合
      manifestModules = new ManifestParser(applicationContext).parse();
    }

    if (annotationGeneratedModule != null
        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
      Set<Class<?>> excludedModuleClasses =
          annotationGeneratedModule.getExcludedModuleClasses();
      Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
      while (iterator.hasNext()) {
        com.bumptech.glide.module.GlideModule current = iterator.next();
        if (!excludedModuleClasses.contains(current.getClass())) {
          continue;
        }
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
        }
        iterator.remove();
      }
    }

    ...

    //RequestManager的工厂类
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory() : null;
    //设置RequestManagerRetriever的RequestManagerFactory
    builder.setRequestManagerFactory(factory);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    Glide glide = builder.build(applicationContext);//创建Glide实例
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.registerComponents(applicationContext, glide, glide.registry);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }

    //监听应用低内存情况,清空memoryCache,bitmapPool,arrayPool;
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

--------------------------------------  ComponentCallbacks接口的实现方法    -----------------------------------------

  //复写ComponentCallbacks接口方法
  @Override
  public void onConfigurationChanged(Configuration newConfig) {
    // Do nothing.
  }

  //复写ComponentCallbacks接口方法,低内存时清理缓存
  @Override
  public void onLowMemory() {
    clearMemory();
  }

分析:

  • get(@NonNull Context context) 使用单例设计模式,加上checkAndInitializeGlide方法中的判断标志,保证Glide的实例全局只有一个。
  • 实例化Glide前,先利用反射获取AppGlideModule的子类实现和解析AndroidManifest中自定义的GlideModule的metadata标签等等,用于配置GlideBuilder。
  • Glide真正的实例化是通过调用builder.build(applicationContext)。
  • 获取到Glide实例之后,通过applicationContext绑定ComponentCallbacks(Glide实现了ComponentCallbacks接口),监听app的内存不足情况,当内存不足时清空memoryCache,bitmapPool,arrayPool。
3、真正实例化Glide
public final class GlideBuilder {

  private final Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions = new ArrayMap<>();
  private Engine engine;//图片加载引擎,负责启动并管理缓存资源
  private BitmapPool bitmapPool;//Lru策略的图片池
  private ArrayPool arrayPool; //读写IO的Lru策略的数组池
  private MemoryCache memoryCache; // Lru策略的内存缓存池
  private GlideExecutor sourceExecutor; //查找内存缓存的线程池
  private GlideExecutor diskCacheExecutor;//查找本地磁盘缓存的线程池
  private DiskCache.Factory diskCacheFactory;//本地磁盘缓存对象的创建工厂
  private MemorySizeCalculator memorySizeCalculator;//内存计算器,计算内存缓存池的大小
  private ConnectivityMonitorFactory connectivityMonitorFactory;//网络状态监听事件的工厂
  private int logLevel = Log.INFO;
  private RequestOptions defaultRequestOptions = new RequestOptions();//Glide图片请求配置
  @Nullable
  private RequestManagerFactory requestManagerFactory;//Glide的图片配置选项的构建工厂
  private GlideExecutor animationExecutor;//加载动画的线程池
  private boolean isActiveResourceRetentionAllowed;//是否保留图片资源不回收,默认false
  @Nullable
  private List<RequestListener<Object>> defaultRequestListeners;//图片请求回调接口
  private boolean isLoggingRequestOriginsEnabled;

  @NonNull
  Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }

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

    if (animationExecutor == null) {
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }

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

    if (connectivityMonitorFactory == null) {
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

    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(...);
    }

    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

    //实例化requestManagerRetriever
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(...);
  }

}
  1. GlideBuilder的build方法就是初始化一些线程池,缓存,图片请求配置,请求回调等,传递到Glide的构造函数方法,实例化Glide,然后返回Glide的实例。
  2. 在实例化GlideBuilder的同时,传入RequestManagerFactory实例,构建RequestManagerRetriever实例。

在回到第一part的with方法,with(xxx)方法调用了getRetriever(xxx).get(xxx),即调用RequestManagerRetriever的get方法获取RequestManager;

4、RequestManagerRetriever.get(xxx)
  //记录FragmentManager和RequestManagerFragment的映射
  //RequestManagerFragment是fragment的子类,以子fragment添加到图片加载页面中
  @VisibleForTesting
  final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments =
      new HashMap<>();

  @VisibleForTesting
  final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments =
      new HashMap<>();
  

  //在with(context)方法就是通过获取RequestManagerRetriever实例,然后调用get(context)来获取RequestManager
  @NonNull
  public RequestManager get(@NonNull Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        return get((Activity) context);
      } else if (context instanceof ContextWrapper) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }

    return getApplicationManager(context);
  }

  //主线程时,往下调用supportFragmentGet方法
  @NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(
          activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

   //主线程时,往下调用supportFragmentGet方法
  @NonNull
  public RequestManager get(@NonNull android.support.v4.app.Fragment fragment) {
    Preconditions.checkNotNull(fragment.getActivity(),
          "You cannot start a load on a fragment before it is attached or after it is destroyed");
    if (Util.isOnBackgroundThread()) {
      return get(fragment.getActivity().getApplicationContext());
    } else {
      FragmentManager fm = fragment.getChildFragmentManager();
      return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
    }
  }

  //主线程时,往下调用fragmentGet方法
  @SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(
          activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

  //主线程时,往下调用fragmentGet方法
  @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 {
      android.app.FragmentManager fm = fragment.getChildFragmentManager();
      return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
    }
  }

调用get(xxx)方法时都会判断是否在主线程中调用,另外判断传入的参数是FragmentActivity、Frgament(Support V4)、Activity、Frgamet(非Support V4)中的哪一个类型。都会进入以下三个方法中的其中一个:

  • getApplicationManager();执行条件:在子线程调用Glide.with()方法,或者Glide.with(xxx)传入参数类型是Application。
  • supportFragmentGet();执行条件:在主线程调用Glide.with()方法;或者Glide.with(xxx)传入的参数类型是FragmentActiviy或Support V4包中的Fragment。
  • fragmentGet();执行条件:在主线程调用Glide.with()方法;或者Glide.with(xxx)传入的参数类型是Activiy(非Fragment)或非Support V4包中的Fragment。
5、创建RequestManager实例
  private RequestManager getApplicationManager(@NonNull Context context) {
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          Glide glide = Glide.get(context.getApplicationContext());
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }

    return applicationManager;
  }

  
  private RequestManager supportFragmentGet(
      @NonNull Context context,
      @NonNull FragmentManager fm,
      @Nullable Fragment parentHint,
      boolean isParentVisible) {
    //获取Glide自定义的SupportRequestManagerFragment,
    //这个fragment并不可见,用来绑定并监听页面的生命周期方法
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();

    //如果Fragment中的requestManager为空,初始化一个,并set给Fragment
    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);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }


  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    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);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

getApplicationManager()、supportFragmentGet()和fragmentGet()方法都是通过RequestManagerRetriever.RequestManagerFactory的build方法创建RequestManager。

  //获取缓存中的SupportRequestManagerFragment,
  //如果缓冲中没有就新建一个,然后绑定到页面中,用来监听页面的生命周期
  private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    SupportRequestManagerFragment current =
        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingSupportRequestManagerFragments.get(fm);
      if (current == null) {
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();//调用lifecycle的onStart()
        }
        pendingSupportRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }


  //逻辑和getSupportRequestManagerFragment一样
  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

}
  1. SupportRequestManagerFragment是Glide自定义的fragment,用来同步给定页面的生命周期,管理图片请求的开始和结束。
  2. 通过fm.findFragmentByTag(FRAGMENT_TAG)方法来获取SupportRequestManagerFragment,说明一个FragmentManager对应一个SupportRequestManagerFragment,同时RequestManager会设置给SupportRequestManagerFragment的,所以一个SupportRequestManagerFragment对应一个RequestManager,所以一个Activity或者一个Fragment对应一个RequestManager

总结:Glide.with(xxx)第一步是初始化Glide中的线程池,缓存等等一些图片下载需要的资源;第二步是判断Glide调用的位置,给页面设置RequestManager,绑定图片和页面的生命周期。

with(xxx)方法调用流程图:

with流程图.png
拓展:将图片请求绑定Activity/frament的生命周期
public class RequestManagerFragment extends Fragment {

  private final ActivityFragmentLifecycle lifecycle;
  
  //新建RequestManagerFragment时,同时会新建一个ActivityFragmentLifecycle
  public RequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }

  ...

  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }

  @Override
  public void onStop() {
    super.onStop();
    lifecycle.onStop();
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    lifecycle.onDestroy();
    unregisterFragmentWithRoot();
  }

}

RequestManagerFragment构造方法会同时创建ActivityFragmentLifecycle,其生命周期方法回调时也会ActivityFragmentLifecycle中对应的生命周期方法。

ActivityFragmentLifecycle


//Lifecycle接口,用来定义加入和删除LifecycleListener方法
public interface Lifecycle {
  void addListener(@NonNull LifecycleListener listener);
  void removeListener(@NonNull LifecycleListener listener);
}

//用来管理fragment对应的LifecycleListener,调用对应onStart和onStop
class ActivityFragmentLifecycle implements Lifecycle {
  private final Set<LifecycleListener> lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
  private boolean isStarted;
  private boolean isDestroyed;

  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.add(listener);

    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.remove(listener);
  }

  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }

  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }
}

ActivityFragmentLifecycle实现了Lifecycle接口,内部有一个set的集合来管理多个LifecycleListener。

RequestManager

//RequestManager的构造方法会把自己添加到Lifecycle的LifecycleListener集合中,让Lifecycle进行管理
public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {

  private final TargetTracker targetTracker = new TargetTracker();

  private final Runnable addSelfToLifecycle = new Runnable() {
    @Override
    public void run() {
      lifecycle.addListener(RequestManager.this);
    }
  };

  public RequestManager(
      @NonNull Glide glide, @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
    this(...);
  }

  // Our usage is safe here.
  @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
  RequestManager(...) {
    this.glide = glide;
    ...

    //把RequestManager自己添加到lifecycle的LifecycleListener集合中
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);
    ...
  }

  @Override
  public synchronized void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }


  @Override
  public synchronized void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }

  /**
   * Lifecycle callback that cancels all in progress requests and clears and recycles resources for
   * all completed requests.
   */
  @Override
  public synchronized void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }

}

RequestManager实现了LifecycleListener接口,同时RequestManager的构造方法会把自己添加到Lifecycle的LifecycleListener集合中,让Lifecycle进行管理。同时RequestManager是Glide中管理图片请求启动与暂停的类。

结论:RequestManagerFragment内部持有ActivityFragmentLifecycle变量,ActivityFragmentLifecycle内部持有LifecycleListener的集合,RequestManager是一个LifecycleListener,同时RequestManager构造方法会把自身添加到ActivityFragmentLifecycle内部的LifecycleListener集合。所以当我们的页面生命周期的onStart()和onStop()回调时,会回调Glide图片请求的启动和暂停。

onStart调用链.png
onStop调用链.png

相关文章

网友评论

    本文标题:Glide with(xxx)源码分析

    本文链接:https://www.haomeiwen.com/subject/pfeunctx.html