读源码-Glide源码解析

本文详细介绍了Glide的源码解析,从Glide.with()的初始化过程,到RequestManager的获取,再到load()的加载准备和into()的图片显示。重点阐述了Glide的三级缓存机制,包括内存缓存和硬盘缓存的使用。通过源码分析,展示了Glide如何优雅地处理图片加载和显示。
摘要由CSDN通过智能技术生成


本文基于Glide版本:

com.github.bumptech.glide:glide:4.11.0

Glide最常用的一行代码如下,也概括了Glide的初始化、加载图片(本地、缓存、网络图片)、绑定显示的流程。本文就从该行代码开启Glide的源码之旅。

Glide.with(this).load(url).into(mainPic);

1-初始化with()

首先是Glide.with()方法,通过该方法主要是通过RequestManagerRetriever获取一个RequestManager对象。RequestManager是处理图片加载过程的具体实现类,后面详细讲述。

调用链路:(1)Glide.with

–>(2)Glide.getRetriever
–>(3)Glide.get
–>(4)Glide.getRequestManagerRetriever
–>(5)RequestManagerRetriever.get
–>(6)RequestManager

(1)Glide.with

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

(2)Glide.getRetriever获取RequestManagerRetriever

private static RequestManagerRetriever getRetriever(@Nullable Context context) {
   
    //判空检测,判断对象空指针以及Activity/Fragment是否处于活跃状态
    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();
}

(3)Glide.get(context)获取Glide的全局单例。这么多逻辑主要是处理用户自定义AppGlideModule的情况。

  • 继承AppGlideModule实现自定义Glide,重写网络加载框架、缓存路径、自定义缓存等定制内容,在class前加上@GlideModule注解
  • 通过Annotation Processer在编译时根据@GlideModule注解来生成自定义Glide的代理类GeneratedAppGlideModuleImpl
  • 通过反射获取代理类的构造方法并实例化返回
  • 若APT方法获取失败则尝试从manifest文件中获取自定义GlideModule。manifest配置自定义module是Glide4.0以前的方式,新版本基本都采用注解APT的方式实现。
  • 若都没有自定义的module,则通过GliderBuilder的工厂模式生成实例。
public static Glide get(@NonNull Context context) {
   
    if (glide == null) {
   
        //获取自定义AppGlideModule的代理类GeneratedAppGlideModuleImpl   
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
   
        if (glide == null) {
   
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }
    return glide;
}

(4)Glide.getRequestManagerRetriever获取Glide.get方法中初始化的RequestManagerRetriever对象。

public RequestManagerRetriever getRequestManagerRetriever() {
   
    return requestManagerRetriever;
}

(5)RequestManagerRetriever.get方法根据调用的context及是否主线程返回对应的RequestManager。context为FragmentActivity时调用:

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)) {
   
    //Activity、FragmentActivity情况
      if (context instanceof FragmentActivity) {
   
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
   
        return get((Activity) context);
      } else if (context instanceof ContextWrapper
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
   
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
    //非UI线程情况
    return getApplicationManager(context);
}

如果context是Fragment时调用:

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");
    //非UI线程
    if (Util.isOnBackgroundThread()) {
   
      return get(fragment.getContext().getApplicationContext());
    } else {
   
        //context为Fragment情况
      FragmentManager fm = fragment.getChildFragmentManager();
      return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值