Glide源码学习

前言

开始

基本使用非常简单,链式调用把context对象传入,设置要加载的URL,设置要填充的ImageView控件,方法很简洁,每次都是传入的最核心的参数,底层加载的缓存逻辑,加载的引擎,加载的对象的适配,URL的适配...都为我们做了封装。使用者无需关心这些细节就可以实现图片的加载。这才是优秀的库该有的样子足够简洁,但是足够强大。把复杂留给自己,把简单留给用户。

Glide.with(fragment)
    .load(myUrl)
    .into(imageView);

With方法

前面看了Glide的基本使用,Glide是外观类,我们先看前面例子中的with方法

with相关的重载方法有四个,最终都是返回一个RequestManager,后面调用load方法用的就是返回的RequestManager。

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

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

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

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

都是先调用getRetriever(),getRetriever()方法是Glide的静态方法,会返回一个RequestManagerRetriever。这个方法中会引出Glide的构造,最终通过调用Glide实例的getRequestManagerRetriever方法返回RequestManagerRetriever。

@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, DESTROYED_ACTIVITY_WARNING);
    return Glide.get(context).getRequestManagerRetriever();
}

//双重校验锁单例模式获取Glide,glide实例是被volatile修饰
@NonNull
// Double checked locking is safe here.
@SuppressWarnings("GuardedBy")
public static Glide get(@NonNull Context context) {
    if (glide == null) {
      //这里通过反射创建一个GeneratedAppGlideModuleImpl的实例
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
          //检查是否初始化过Glide
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }

    return glide;
  }

继续看checkAndInitializeGlide方法,检查并初始化Glide

static void checkAndInitializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    // In the thread running initGlide(), one or more classes may call Glide.get(context).
    //初始化中,其他类也可能调用Glide.get
    // Without this check, those calls could trigger infinite recursion.
    //如果没有这个校验,有可能触发无线递归
    
    if (isInitializing) {
      throw new IllegalStateException(
          "Glide has been called recursively, this is probably an internal library error!");
    }
    //标记正在初始化中
    isInitializing = true;
    try {
      initializeGlide(context, generatedAppGlideModule);
    } finally {
      //标记初始化中为false
      isInitializing = false;
    }
  }
  
   @GuardedBy("Glide.class")
  private static void initializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    //新建一个GlideBuilder传入
    initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
  }
  
  
  private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    //获取getApplicationContext,这里我们要知道构造Glide是全局唯一的
    Context applicationContext = context.getApplicationContext();
    List<GlideModule> manifestModules = Collections.emptyList();
    //GlideModule相关处理,先忽略
    ...

    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
    builder.setRequestManagerFactory(factory);
    for (GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    //构造Glide
    Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
    //注册ComponentCallback
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

这里注意在initializeGlide方法中用的是applicationContext,不依赖某个Activity,Service,Fragment等。为什么提一下这个,因为后面RequestManager的生成不是这样的,后面做下区分。

@NonNull
  Glide build(
      @NonNull Context context,
      List<GlideModule> manifestModules,
      AppGlideModule annotationGeneratedGlideModule) {
    //设置资源执行器
    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();
    }

    //构造Bitmap复用池
    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(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

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

    GlideExperiments experiments = glideExperimentsBuilder.build();
    //新建一个RequestManagerRetriever
    //这里注意后面load方法会用到这个requestManagerRetriever来获取RequestManager
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    //构造Glide,传入以上实例作为参数
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        manifestModules,
        annotationGeneratedGlideModule,
        experiments);
  }

构造方法

Glide(
      @NonNull Context context,
      @NonNull Engine engine,
      @NonNull MemoryCache memoryCache,
      @NonNull BitmapPool bitmapPool,
      @NonNull ArrayPool arrayPool,
      @NonNull RequestManagerRetriever requestManagerRetriever,
      @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
      int logLevel,
      @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
      @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
      @NonNull List<RequestListener<Object>> defaultRequestListeners,
      @NonNull List<GlideModule> manifestModules,
      @Nullable AppGlideModule annotationGeneratedModule,
      @NonNull GlideExperiments experiments) {
    this.engine = engine;
    this.bitmapPool = bitmapPool;
    this.arrayPool = arrayPool;
    this.memoryCache = memoryCache;
    this.requestManagerRetriever = requestManagerRetriever;
    this.connectivityMonitorFactory = connectivityMonitorFactory;
    this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;

    // This has a circular relationship with Glide and GlideContext in that it depends on both,
    // but it's created by Glide's constructor. In practice this shouldn't matter because the
    // supplier holding the registry should never be initialized before this constructor finishes.
    GlideSupplier<Registry> registry =
        RegistryFactory.lazilyCreateAndInitializeRegistry(
            this, manifestModules, annotationGeneratedModule);

    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    //新建一个GlideContext,并传递大部分构造方法的参数进去
    glideContext =
        new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptionsFactory,
            defaultTransitionOptions,
            defaultRequestListeners,
            engine,
            experiments,
            logLevel);
  }

现在getRetriever()方法基本看完,核心就是为我们构造出了Glide单例,然后调用Glide的getRequestManagerRetriever()得到RequestManagerRetriever

@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
    return requestManagerRetriever;
}

这个requestManagerRetriever在Glide构造方法的时候看到过,构造的时候,新建并传递了requestManagerRetriever参数。现在让我们回退再回到with方法,先通过getRetriever方法得到一个RequestManagerRetriever,然后调用它的get方法。下面去看RequestManagerRetriever的get方法,get方法主要是获取一个RequestManager。基本上跟Glide的with方法一一对应,不一样的是with方法最终都调用到了一个方法,而这个get实现都有些区别。

@NonNull
public RequestManager get(@NonNull Context context) {...}

@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {...}

@NonNull
public RequestManager get(@NonNull Fragment fragment) {...}

@NonNull
public RequestManager get(@NonNull View view) {...}

上面这四种,第四种其实是分情况如果找到这个View的Activity,Activity是否是属于FragmentActivity,是FragmentActivity的话是否是属于Fragment等最终是调用前三种的一个,所以主要分为三种类型:

  • 参数为FragmentActivity
  • 参数为Fragment
  • 参数为Context

参数为FragmentActivity

 public RequestManager get(@NonNull FragmentActivity activity) {
    ...
    //是否可见
    boolean isActivityVisible = isActivityVisible(activity);
    //获取Glide单例
    Glide glide = Glide.get(activity.getApplicationContext());
    //调用lifecycleRequestManagerRetriever的getOrCreate
    
    return lifecycleRequestManagerRetriever.getOrCreate(
        activity,
        glide,
        activity.getLifecycle(),
        activity.getSupportFragmentManager(),
        isActivityVisible);
  }

lifecycleRequestManagerRetriever是在RequestManagerRetriever构造方法中新建的,也就意味着Glide单例新建之前已经构造好了lifecycleRequestManagerRetriever实例。

注意第三个参数是getLifecycle,只有ComponentActivity才有这个方法,Activity中是没有这个方法的,这也就是为什么这个参数传入的不是Activity的原因。通过这个Lifecycle可以监控activity的生命周期。也就能及时回收,避免发生内存泄露。

接着看getOrCreate

RequestManager getOrCreate(
      Context context,
      Glide glide,
      final Lifecycle lifecycle,
      FragmentManager childFragmentManager,
      boolean isParentVisible) {
    //断言在主线程,不在的话抛异常
    Util.assertMainThread();
    
    //看名字大概是根据lifecycle为key,获取唯一的RequestManager
    RequestManager result = getOnly(lifecycle);
    if (result == null) {
      //LifecycleLifecycle这名字起的。。其实是它实现了glide自己的Lifecycle
      //同时又实现了Android的LifecycleObserver
      LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
      //构造一个新的
      result =
          factory.build(
              glide,
              glideLifecycle,
              new SupportRequestManagerTreeNode(childFragmentManager),
              context);
      //存放到lifecycleToRequestManager这个Map中
      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) {
        //如果Parent可见,直接执行onStart()方法
        result.onStart();
      }
    }
    //返回RequestManager
    return result;
  }

接着看RequestManager的构建,这里使用的是工厂模式,factory是LifecycleRequestManagerRetriever构造的时候传入的,LifecycleRequestManagerRetriever的构造是在RequestManagerRetriever的构造方法中,也就是Glide构造之前。RequestManagerRetriever的构造方法中传入了factory,为空的话会使用DEFAULT_FACTORY,什么时候不为空呢,就是在initializeGlide方法中annotationGeneratedModule.getRequestManagerFactory()不为空,这里先不深入,我们直接看DEFAULT_FACTORY。

private static final RequestManagerFactory DEFAULT_FACTORY =
      new RequestManagerFactory() {
        @NonNull
        @Override
        public RequestManager build(
            @NonNull Glide glide,
            @NonNull Lifecycle lifecycle,
            @NonNull RequestManagerTreeNode requestManagerTreeNode,
            @NonNull Context context) {
            直接new了一个RequestManager
          return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
        }
      };

最终调用到

RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.context = context;

    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

    // Order matters, this might be unregistered by teh listeners below, so we need to be sure to
    // register first to prevent both assertions and memory leaks.
    glide.registerRequestManager(this);

    // If we're the application level request manager, we may be created on a background thread.
    // In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
    // issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
    // This should be entirely safe.
    if (Util.isOnBackgroundThread()) {
      Util.postOnUiThread(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
  }

参数为Fragment

基本同参数为FragmentActivity,不同的是lifecycle这里获取的是fragment.getLifecycle(),感兴趣的可以自行查阅源码

参数为Context

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 ContextWrapper
          // Only unwrap a ContextWrapper if the baseContext has a non-null application context.
          // Context#createPackageContext may return a Context without an Application instance,
          // in which case a ContextWrapper may be used to attach one.
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }

    return getApplicationManager(context);
  }

到这里我们了解了RequestManager的生成过程。

总结:With阶段主要为:

  • 获取RequestManagerRetriever,获取过程中若未构建Glide,帮我们构建好Glide单例
  • 有了RequestManagerRetriever,通过RequestManagerRetriever的get方法获取RequestManager,不同的context(Activity,Fragment,ApplicationContext)得到不同的RequestManager

至此,with方法分析完成,为我们完成加载图片前的平台侧准备工作,这里的平台指的是Glide。

load方法解析

前面讲解构造函数知道load(url)是RequestManager的方法,RequestManager是用来管理和启动request的。

A class for managing and starting requests for Glide.

RequestManager是with方法中getRetriever(context).get(context)获取的。getRetriever(context)得到RequestManagerRetriever,然后调用RequestManagerRetriever的get方法获取RequestManager。

现在去看下load方法,这里我们就比较熟悉了,我们知道glide非常贴心的为我们支持了很多类型,Bitmap,url,drawable, 资源id,文件等等。

//RequestManager.java
  public RequestBuilder<Drawable> load(@Nullable Bitmap bitmap) {
    return asDrawable().load(bitmap);
  }
  
  public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
  }
  
  public RequestBuilder<Drawable> load(@Nullable Uri uri) {
    return asDrawable().load(uri);
  }
  
  public RequestBuilder<Drawable> load(@Nullable File file) {
    return asDrawable().load(file);
  }
  
  public RequestBuilder<Drawable> load(@RawRes @DrawableRes @Nullable Integer resourceId) {
    return asDrawable().load(resourceId);
  }
  
  public RequestBuilder<Drawable> load(@Nullable URL url) {
    return asDrawable().load(url);
  }
  
  public RequestBuilder<Drawable> load(@Nullable byte[] model) {
    return asDrawable().load(model);
  }
  
  public RequestBuilder<Drawable> load(@Nullable Object model) {
    return asDrawable().load(model);
  }

他们都调用了一个asDrawable()方法,返回一个RequestBuilder,是一个泛型类,可以处理泛型资源类型的设置选项和开始加载。既然是泛型类,除了这里的Drawable,还用到哪些类型呢?还有Bitmap,GifDrawable,File,这里主要分析核心流程,这里主要看Drawable,也是我们最常用的。下面去看下asDrawable的实现。

  public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
  }
  
  public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    //构造RequestBuilder,注意这几个参数,第一个参数是glide对象,第二个是RequestManager自身,
    //第三个是resourceClass,也即是传进来的Drawable.class对象,第四个是上下文
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }

asDrawable()也是返回一个RequestBuilder,前面RequestManager的load方法中都是调用了asDrawable().load方法,也就是RequestBuilder的load方法,说明后面执行load方法的也是新建的这个RequestBuilder执行的。然后再来看下

//RequestBuilder.java
  public RequestBuilder<TranscodeType> load(@Nullable String string) {
    //把参数传过去
    return loadGeneric(string);
  }
  
  @NonNull
  private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    if (isAutoCloneEnabled()) {
      return clone().loadGeneric(model);
    }
    //这里model是一个Object,也就是可以接受任意类型
    this.model = model;
    isModelSet = true;
    return selfOrThrowIfLocked();
  }

其实就是给this.mode赋值,然后设置isModelSet为true,然后返回自身,也就是刚刚新建的RequestBuilder,RequestBuilder是BaseRequestOptions的子类。

//BaseRequestOptions.java
  protected final T selfOrThrowIfLocked() {
    if (isLocked) {
      throw new IllegalStateException("You cannot modify locked T, consider clone()");
    }
    return self();
  }
  
  private T self() {
    return (T) this;
  }

总结:load方法看着比较简单,仅仅是构造了一个RequestBuilder,后面调用的into方法也在RequestBuilder中,所以可以认为这里仅仅是对请求参数的一个准备,适配了所有的类型Bitmap,url,drawable, 资源id,文件等等。

into方法分析

前面主要是拿到了RequestBuilder对象,执行into方法的是在RequestBuilder中

//RequestBuilder.java
@NonNull
  public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    //检查是否在主线程,否则抛异常
    Util.assertMainThread();
    //检查要显示图片的view是否为空
    Preconditions.checkNotNull(view);

    //赋值BaseRequestOptions,RequestBuilder继承自BaseRequestOptions
    BaseRequestOptions<?> requestOptions = this;
    //判断是否设置Transformation等变换
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {
      // Clone in this method so that if we use this RequestBuilder to load into a View and then
      // into a different target, we don't retain the transformation applied based on the previous
      // View's scale type.
      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());
  }

看下传入的几个参数

  • glideContext.buildImageViewTarget(view, transcodeClass) -> 构建一个Target对象

  • null->targetListener传入的为空

  • requestOptions->也就是自身

  • Executor->这里传入的是主线程Executor
    这里我们先看下Target的构造过程,后面会用到

    //GlideContext.java
    public <X> ViewTarget<ImageView, X> buildImageViewTarget(
    @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
    //将ImageView和transcodeClass调用imageViewTargetFactory的buildTarget
    return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
    }

ImageViewTargetFactory的buildTarget方法是根据transcodeClass类型创建不同的Target,如BitmapImageViewTarget和DrawableImageViewTarget

//ImageViewTargetFactory.java
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)");
    }
  }

//RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    //检查target是否为null
    Preconditions.checkNotNull(target);
    //还记得前面load方法中有设置这个为true
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

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

    Request previous = target.getRequest();
    //拿到上一次的request,如果和以前的一样
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      //如果request已经完成,重新开始以保证结果可以被传递
      //如果request已经失败,重新开始请求,给它第二次成功的机会
      //如果在运行,我们让他继续运行
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        // Use the previous request rather than the new one to allow for optimizations like skipping
        // setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
        // that are done in the individual Request.
        previous.begin();
      }
      return target;
    }

    //清空target
    requestManager.clear(target);
    //给target设置为当前的request
    target.setRequest(request);
    //添加追踪,并开始执行
    requestManager.track(target, request);

    return target;
  }

后面分三个方向,这三个方法也是into方法主要做的几件事:

  • 如何构造request
  • 如何请求request
  • 如何把请求结果显示到ImageView上

如何构造request

private Request buildRequest(
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {
    return buildRequestRecursive(
        /* requestLock= */ new Object(),//请求锁
        target,//目标
        targetListener,//目标监听器,前面看到这里传来的是null
        /* parentCoordinator= */ null,
        transitionOptions,//转换选项
        requestOptions.getPriority(),//请求选项-优先级
        requestOptions.getOverrideWidth(),//请求选项-复写宽度
        requestOptions.getOverrideHeight(),//请求选项-复写高度
        requestOptions,//请求选项
        callbackExecutor //回调执行器
        );
  }
  
  
private Request buildRequestRecursive(...) {

    // Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
    ErrorRequestCoordinator errorRequestCoordinator = null;
    //前面Demo没有设置error,这里为null
    if (errorBuilder != null) {
      errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
      parentCoordinator = errorRequestCoordinator;
    }

    Request mainRequest =
        buildThumbnailRequestRecursive(
            requestLock,
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);

    if (errorRequestCoordinator == null) {
      return mainRequest;
    }
    ...
    return errorRequestCoordinator;
  }

private Request buildThumbnailRequestRecursive(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {
    if (thumbnailBuilder != null) {
      //前面Demo中没有设置thumbnail,不会走到这里先忽略
      ...
    } else if (thumbSizeMultiplier != null) {
      //前面Demo中没有设置thumbnail,不会走到这里先忽略
      ...
    } else {
      // Base case: no thumbnail.
      return obtainRequest(
          requestLock,
          target,
          targetListener,
          requestOptions,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          callbackExecutor);
    }
  }

最后走到obtainRequest,通过SingleRequest.obtain,最终在SingleRequest.java中直接新建了一个SingleRequest

private Request obtainRequest(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      RequestCoordinator requestCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      Executor callbackExecutor) {
    return SingleRequest.obtain(
        context,
        glideContext,
        requestLock,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(),
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
  }

如何请求request

通过看Request接口说明,知道begin()是开始一个请求,在前面requestManager.track(target, request);会最终调用到begin()方法。

  //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);
    if (!isPaused) {
      //启动
      request.begin();
    } else {
      request.clear();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      pendingRequests.add(request);
    }
  }

public interface Request {
  //启动一个异步请求
  void begin();

  //取消,清空请求
  void clear();

  //暂停请求
  void pause();

  //是否在运行中
  boolean isRunning();

  //请求是否完成
  boolean isComplete();

  //请求是否被clear
  boolean isCleared();

  /**
   * Returns true if a resource is set, even if the request is not yet complete or the primary
   * request has failed.
   */
  boolean isAnyResourceSet();

  //和另一个请求是否相等
  boolean isEquivalentTo(Request other);
}

下面我们去看SingleRequest的begin方法的实现

//SingleRequest.java
public void begin() {
    synchronized (requestLock) {
      assertNotCallingCallbacks();
      stateVerifier.throwIfRecycled();
      startTime = LogTime.getLogTime();
      if (model == null) {
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
          width = overrideWidth;
          height = overrideHeight;
        }
        // Only log at more verbose log levels if the user has set a fallback drawable, because
        // fallback Drawables indicate the user expects null models occasionally.
        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 we're restarted after we're complete (usually via something like a notifyDataSetChanged
      // that starts an identical request into the same Target or View), we can simply use the
      // resource and size we retrieved the last time around and skip obtaining a new size, starting
      // a new load etc. This does mean that users who want to restart a load because they expect
      // that the view size has changed will need to explicitly clear the View or Target before
      // starting the new load.
      if (status == Status.COMPLETE) {
        onResourceReady(
            resource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
        return;
      }

      // Restarts for requests that are neither complete nor running can be treated as new requests
      // and can run again from the beginning.

      experimentalNotifyRequestStarted(model);

      cookie = GlideTrace.beginSectionAsync(TAG);
      status = Status.WAITING_FOR_SIZE;
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        //如果overrideWidth,overrideHeight都是有效的,直接调用onSizeReady
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        //否则调用target.getSize,并把自身传入,因为SingleRequest实现了SizeReadyCallback,获取成功最终还是回调到onSizeReady方法
        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));
      }
    }
  }

最终都是调用到onSizeReady方法,onSizeReady方法中调用的是engine的load方法,engine是在Glide的建造者中构造的

//SingleRequest.java
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) {
        //如果还在等待size结果。直接返回
        return;
      }
      //将status设置为Status.RUNNING
      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));
      }
      //调用引擎的load方法加载图片
      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);

      // This is a hack that's only useful for testing right now where loads complete synchronously
      // even though under any executor running on any thread but the main thread, the load would
      // have completed asynchronously.
      if (status != Status.RUNNING) {
        loadStatus = null;
      }
      if (IS_VERBOSE_LOGGABLE) {
        logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
      }
    }
  }

需要注意的是load方法传入了一个ResourceCallback cb参数,这个接口就是加载结果的回调。

public interface ResourceCallback {
  //加载成功
  void onResourceReady(
      Resource<?> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey);
  //加载失败
  void onLoadFailed(GlideException e);

  Object getLock();
}

//Engine.java
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) {
      //先重缓存中加载
      memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

      if (memoryResource == null) {
        //缓存没有
        return waitForExistingOrStartNewJob(
            glideContext,
            model,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            options,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache,
            cb,
            callbackExecutor,
            key,
            startTime);
      }
    }

    // Avoid calling back while holding the engine lock, doing so makes it easier for callers to
    // deadlock.
    cb.onResourceReady(
        memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
    return null;
  }

分析缓存加载流程

//Engine.java
private EngineResource<?> loadFromMemory(
      EngineKey key, boolean isMemoryCacheable, long startTime) {
    if (!isMemoryCacheable) {
      return null;
    }
    //先从活跃缓存中加载
    EngineResource<?> active = loadFromActiveResources(key);
    if (active != null) {
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from active resources", startTime, key);
      }
      return active;
    }

    //活跃缓存没有找到,继续去非活跃缓存中加载
    EngineResource<?> cached = loadFromCache(key);
    if (cached != null) {
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from cache", startTime, key);
      }
      return cached;
    }
    //都没查到,返回null
    return null;
  }

活跃缓存是直接在Map中

private EngineResource<?> loadFromActiveResources(Key key) {
    //ActiveResources的实例,里面存放的是Map<Key, ResourceWeakReference>
    EngineResource<?> active = activeResources.get(key);
    if (active != null) {
      active.acquire();
    }

    return active;
  }

从缓存中加载,缓存对象是Engine构造的时候传入的,最开始在Glide构建时候新建的LruResourceCache,是Glide自己实现的LRU

  private EngineResource<?> loadFromCache(Key key) {
    EngineResource<?> cached = getEngineResourceFromCache(key);
    if (cached != null) {
      cached.acquire();
      activeResources.activate(key, cached);
    }
    return cached;
  }
  
  private EngineResource<?> getEngineResourceFromCache(Key key) {
    Resource<?> cached = cache.remove(key);

    final EngineResource<?> result;
    if (cached == null) {
      result = null;
    } else if (cached instanceof EngineResource) {
      // Save an object allocation if we've cached an EngineResource (the typical case).
      result = (EngineResource<?>) cached;
    } else {
      result =
          new EngineResource<>(
              cached,
              /* isMemoryCacheable= */ true,
              /* isRecyclable= */ true,
              key,
              /* listener= */ this);
    }
    return result;
  }

缓存没有查到,会调用waitForExistingOrStartNewJob方法,等待已经存在的任务或者开启新的任务。

//Engine.java
private <R> LoadStatus waitForExistingOrStartNewJob(...) {
    //先从jobs里面查询是否有加入过
    EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
    if (current != null) {
      current.addCallback(cb, callbackExecutor);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Added to existing load", startTime, key);
      }
      //查询到,直接返回LoadStatus,加载的状态
      return new LoadStatus(cb, current);
    }
    //没查到,通过engineJobFactory工厂构建一个新的EngineJob
    EngineJob<R> engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);
    //在通过解码job工厂构建一个新的解码job
    DecodeJob<R> decodeJob =
        decodeJobFactory.build(
            glideContext,
            model,
            key,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            onlyRetrieveFromCache,
            options,
            engineJob);
    //添加到 jobs里面
    jobs.put(key, engineJob);
    //添加回调
    engineJob.addCallback(cb, callbackExecutor);
    //启动加载工作
    engineJob.start(decodeJob);

    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Started new load", startTime, key);
    }
    //返回加载状态
    return new LoadStatus(cb, engineJob);
  }

下面分析几个点

  • Jobs
  • LoadStatus
  • EngineJob
  • DecodeJob

Jobs

Jobs比较简单,可以理解为就是个工作存储器。有两个Map,

  • jobs 存储普通服务的Map

  • onlyCacheJobs 存储只从缓存取的job的Map

    final class Jobs {
    private final Map<Key, EngineJob<?>> jobs = new HashMap<>(); private final Map<Key, EngineJob<?>> onlyCacheJobs = new HashMap<>();

    @VisibleForTesting
    Map<Key, EngineJob<?>> getAll() {
      return Collections.unmodifiableMap(jobs);
    }
    
    EngineJob<?> get(Key key, boolean onlyRetrieveFromCache) {
      return getJobMap(onlyRetrieveFromCache).get(key);
    }
    
    void put(Key key, EngineJob<?> job) {
      getJobMap(job.onlyRetrieveFromCache()).put(key, job);
    }
    
    void removeIfCurrent(Key key, EngineJob<?> expected) {
      Map<Key, EngineJob<?>> jobMap = getJobMap(expected.onlyRetrieveFromCache());
      if (expected.equals(jobMap.get(key))) {
        jobMap.remove(key);
      }
    }
    
    private Map<Key, EngineJob<?>> getJobMap(boolean onlyRetrieveFromCache) {
      return onlyRetrieveFromCache ? onlyCacheJobs : jobs;
    }
    

    }

LoadStatus

LoadStatus就更简单了,仅仅是包装了engineJob和cb()回调。并提供了一个cancel方法。所以核心就是可以取消请求。

public class LoadStatus {
    private final EngineJob<?> engineJob;
    private final ResourceCallback cb;

    LoadStatus(ResourceCallback cb, EngineJob<?> engineJob) {
      this.cb = cb;
      this.engineJob = engineJob;
    }

    public void cancel() {
      synchronized (Engine.this) {
        engineJob.removeCallback(cb);
      }
    }
  }

EngineJob

EngineJob虽然叫job但是并没有实现Runnable接口,在start启动了decodeJob

//EngineJob.java
public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor =
        decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }

DecodeJob

EngineJob其实仅仅是对DecodeJob的包裹,真正实现请求的地方在DecodeJob。DecodeJob实现了Runnable接口,由线程执行器调度启动。

//DecodeJob.java
public void run() {
    ...
    DataFetcher<?> localFetcher = currentFetcher;
    try {
      if (isCancelled) {
        notifyFailed();
        return;
      }
      runWrapped();
    ...
    } finally {
      // Keeping track of the fetcher here and calling cleanup is excessively paranoid, we call
      // close in all cases anyway.
      if (localFetcher != null) {
        localFetcher.cleanup();
      }
      GlideTrace.endSection();
    }
  }

下面去看runWrapped方法,runWrapped,又调用了getNextStage方法,这里用到了两个设计模式:责任链模式和策略模式。

runReason,执行任务的原因,三种枚举值:

  • INITIALIZE:第一次调度任务
  • WITCH_TO_SOURCE_SERVICE:本地缓存策略失败,尝试重新获取数据,两种情况;当stage为Stage.SOURCE,或者获取数据失败并且执行和回调发生在了不同的线程
  • DECODE_DATA:获取数据成功,但执行和回调不在同一线程,希望回到自己的线程去处理数据

getNextStage:获取下一步的状态

  • INITIALIZE:初始化状态
  • RESOURCE_CACHE:从缓存资源加载
  • DATA_CACHE:从缓存数据加载
  • SOURCE:从源加载获取
  • ENCODE:加载完成后编码成需要的资源
  • FINISHED:完成

getNextGenerator:获取下一个Generator

  • ResourceCacheGenerator :尝试从修改过的资源缓存中获取,如果缓存未命中,尝试从DATA_CACHE中获取

  • DataCacheGenerator 尝试从未修改过的本地缓存中获取数据,如果缓存未命中则尝试从SourceGenerator中获取

  • SourceGenerator 从原始的资源中获取,可能是服务器,也可能是本地的一些原始资源

    //DecodeJob.java
    private void runWrapped() {
    switch (runReason) {
    //首次runReason默认是INITIALIZE
    case INITIALIZE:
    //返回Stage.RESOURCE_CACHE
    stage = getNextStage(Stage.INITIALIZE);
    //
    currentGenerator = getNextGenerator();
    runGenerators();
    break;
    case SWITCH_TO_SOURCE_SERVICE:
    runGenerators();
    break;
    case DECODE_DATA:
    decodeFromRetrievedData();
    break;
    default:
    throw new IllegalStateException("Unrecognized run reason: " + runReason);
    }
    }

    private DataFetcherGenerator getNextGenerator() {
      switch (stage) {
        case RESOURCE_CACHE:
          //首次stage为RESOURCE_CACHE返回ResourceCacheGenerator实例
          return new ResourceCacheGenerator(decodeHelper, this);
        case DATA_CACHE:
          return new DataCacheGenerator(decodeHelper, this);
        case SOURCE:
          return new SourceGenerator(decodeHelper, this);
        case FINISHED:
          return null;
        default:
          throw new IllegalStateException("Unrecognized stage: " + stage);
      }
    }
    
    private Stage getNextStage(Stage current) {
      switch (current) {
        case INITIALIZE:
          //策略模式,根据不同的策略返回不同的结果,默认是ALL那个实例
          return diskCacheStrategy.decodeCachedResource()
              ? Stage.RESOURCE_CACHE
              : getNextStage(Stage.RESOURCE_CACHE);
        case RESOURCE_CACHE:
          return diskCacheStrategy.decodeCachedData()
              ? Stage.DATA_CACHE
              : getNextStage(Stage.DATA_CACHE);
        case DATA_CACHE:
          // Skip loading from source if the user opted to only retrieve the resource from cache.
          return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
        case SOURCE:
        case FINISHED:
          return Stage.FINISHED;
        default:
          throw new IllegalArgumentException("Unrecognized stage: " + current);
      }
    }
    
    private void runGenerators() {
      currentThread = Thread.currentThread();
      startFetchTime = LogTime.getLogTime();
      boolean isStarted = false;
      //首次currentGenerator为ResourceCacheGenerator
      while (!isCancelled
          && currentGenerator != null
          && !(isStarted = currentGenerator.startNext())) {
        //只要返回的isStarted不是true,就不断的去下一个阶段找
        stage = getNextStage(stage);
        currentGenerator = getNextGenerator();
    
        if (stage == Stage.SOURCE) {
          //当stage为Stage.SOURCE的时候表示需要去请求数据,这个时候调用reschedule
          reschedule(RunReason.SWITCH_TO_SOURCE_SERVICE);
          return;
        }
      }
      // We've run out of stages and generators, give up.
      if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
        notifyFailed();
      }
    
      // Otherwise a generator started a new load and we expect to be called back in
      // onDataFetcherReady.
    }
    

以上请求对于我们首次加载的网络图片,最终会走到SourceGenerator的startNext()方法,startNext()又调用到startNextLoad()方法

//SourceGenerator.java
public boolean startNext() {
    ...
    sourceCacheGenerator = null;

    loadData = null;
    boolean started = false;
    while (!started && hasNextModelLoader()) {
      loadData = helper.getLoadData().get(loadDataListIndex++);
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
              || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
        startNextLoad(loadData);
      }
    }
    return started;
  }
  
  private void startNextLoad(final LoadData<?> toStart) {
    loadData.fetcher.loadData(
        helper.getPriority(),
        new DataCallback<Object>() {
          @Override
          public void onDataReady(@Nullable Object data) {
            if (isCurrentRequest(toStart)) {
              onDataReadyInternal(toStart, data);
            }
          }

          @Override
          public void onLoadFailed(@NonNull Exception e) {
            if (isCurrentRequest(toStart)) {
              onLoadFailedInternal(toStart, e);
            }
          }
        });
  }

这里关于数据加载过程,这里暂时不再深入,后面有时间再深入。最终看回调是到了onDataReadyInternal,

//SourceGenerator.java
void onDataReadyInternal(LoadData<?> loadData, Object data) {
    DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
    //如果数据不为空,并且磁盘缓存策略认为这个资源是可以被缓存的,执行写入磁盘操作。
    if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
      dataToCache = data;
      // We might be being called back on someone else's thread. Before doing anything, we should
      // reschedule to get back onto Glide's thread. Then once we're back on Glide's thread, we'll
      // get called again and we can write the retrieved data to cache.
      cb.reschedule();
    } else {
      cb.onDataFetcherReady(
          loadData.sourceKey,
          data,
          loadData.fetcher,
          loadData.fetcher.getDataSource(),
          originalKey);
    }
  }

上面如果磁盘缓存策略认为这个资源是可以被缓存的,执行写入磁盘缓存的操作。具体怎么执行的感兴趣的朋友可以看看。有点绕,不过就像方法名起的那样再次执行,多走了一次圈罢了。又回到DecodeJob的onDataFetcherReady将数据解码出来

public void onDataFetcherReady(
      Key sourceKey, Object data, DataFetcher<?> fetcher, DataSource dataSource, Key attemptedKey) {
    this.currentSourceKey = sourceKey;
    this.currentData = data;
    this.currentFetcher = fetcher;
    this.currentDataSource = dataSource;
    this.currentAttemptingKey = attemptedKey;
    this.isLoadingFromAlternateCacheKey = sourceKey != decodeHelper.getCacheKeys().get(0);

    if (Thread.currentThread() != currentThread) {
      reschedule(RunReason.DECODE_DATA);
    } else {
      GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
      try {
        decodeFromRetrievedData();
      } finally {
        GlideTrace.endSection();
      }
    }
  }
  
 private void decodeFromRetrievedData() {
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey(
          "Retrieved data",
          startFetchTime,
          "data: "
              + currentData
              + ", cache key: "
              + currentSourceKey
              + ", fetcher: "
              + currentFetcher);
    }
    Resource<R> resource = null;
    try {
      //解码过程这里暂不分析
      resource = decodeFromData(currentFetcher, currentData, currentDataSource);
    } catch (GlideException e) {
      e.setLoggingDetails(currentAttemptingKey, currentDataSource);
      throwables.add(e);
    }
    if (resource != null) {
      //解码资源不为空,通知
      notifyEncodeAndRelease(resource, currentDataSource, isLoadingFromAlternateCacheKey);
    } else {
      runGenerators();
    }
  }

private void notifyEncodeAndRelease(
      Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
    GlideTrace.beginSection("DecodeJob.notifyEncodeAndRelease");
    try {
      if (resource instanceof Initializable) {
        ((Initializable) resource).initialize();
      }

      Resource<R> result = resource;
      LockedResource<R> lockedResource = null;
      if (deferredEncodeManager.hasResourceToEncode()) {
        lockedResource = LockedResource.obtain(resource);
        result = lockedResource;
      }

      notifyComplete(result, dataSource, isLoadedFromAlternateCacheKey);

      stage = Stage.ENCODE;
      try {
        if (deferredEncodeManager.hasResourceToEncode()) {
          deferredEncodeManager.encode(diskCacheProvider, options);
        }
      } finally {
        if (lockedResource != null) {
          lockedResource.unlock();
        }
      }
      // Call onEncodeComplete outside the finally block so that it's not called if the encode
      // process
      // throws.
      onEncodeComplete();
    } finally {
      GlideTrace.endSection();
    }
  }
  
//通知完成
private void notifyComplete(
      Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
    setNotifiedOrThrow();
    //最终调用callback的onResourceReady
    callback.onResourceReady(resource, dataSource, isLoadedFromAlternateCacheKey);
  }

这里最终又调用回EngineJob的onResourceReady方法,最终调用到Engine.load方法执行的时候传入的ResourceCallback的onResourceReady。也就是SingleRequest的实现的onResourceReady方法

//EngineJob.java
private class CallResourceReady implements Runnable {

    private final ResourceCallback cb;

    CallResourceReady(ResourceCallback cb) {
      this.cb = cb;
    }

    @Override
    public void run() {
      // Make sure we always acquire the request lock, then the EngineJob lock to avoid deadlock
      // (b/136032534).
      synchronized (cb.getLock()) {
        synchronized (EngineJob.this) {
          if (cbs.contains(cb)) {
            // Acquire for this particular callback.
            engineResource.acquire();
            callCallbackOnResourceReady(cb);
            removeCallback(cb);
          }
          decrementPendingCallbacks();
        }
      }
    }
  }

如何把请求结果显示到ImageView上

前面分析到,请求的结果最终回调到SingleRequest的实现的onResourceReady方法中

public void onResourceReady(
      Resource<?> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
    stateVerifier.throwIfRecycled();
    Resource<?> toRelease = null;
    try {
      synchronized (requestLock) {
        loadStatus = null;
        if (resource == null) {
          //resource为空,抛异常
          GlideException exception =new GlideException(...);
          onLoadFailed(exception);
          return;
        }

        Object received = resource.get();
        if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
          toRelease = resource;
          this.resource = null;
          //抛异常
          GlideException exception =new GlideException(...);
          onLoadFailed(exception);
          return;
        }

        if (!canSetResource()) {
          toRelease = resource;
          this.resource = null;
          // We can't put the status to complete before asking canSetResource().
          status = Status.COMPLETE;
          GlideTrace.endSectionAsync(TAG, cookie);
          return;
        }
        //调用复写的onResourceReady方法
        onResourceReady(
            (Resource<R>) resource, (R) received, dataSource, isLoadedFromAlternateCacheKey);
      }
    } finally {
      if (toRelease != null) {
        engine.release(toRelease);
      }
    }
  }

private void onResourceReady(
      Resource<R> resource, R result, DataSource dataSource, boolean isAlternateCacheKey) {
    // We must call isFirstReadyResource before setting status.
    boolean isFirstResource = isFirstReadyResource();
    status = Status.COMPLETE;
    this.resource = resource;
    ...
    notifyRequestCoordinatorLoadSucceeded();

    isCallingCallbacks = true;
    try {
      boolean anyListenerHandledUpdatingTarget = false;
      if (requestListeners != null) {
        for (RequestListener<R> listener : requestListeners) {
          anyListenerHandledUpdatingTarget |=
              listener.onResourceReady(result, model, target, dataSource, isFirstResource);

          if (listener instanceof ExperimentalRequestListener) {
            ExperimentalRequestListener<R> experimentalRequestListener =
                (ExperimentalRequestListener<R>) listener;
            anyListenerHandledUpdatingTarget |=
                experimentalRequestListener.onResourceReady(
                    result, model, target, dataSource, isFirstResource, isAlternateCacheKey);
          }
        }
      }
      anyListenerHandledUpdatingTarget |=
          targetListener != null
              && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);

      if (!anyListenerHandledUpdatingTarget) {
        Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
        //调用target的onResourceReady方法
        target.onResourceReady(result, animation);
      }
    } finally {
      isCallingCallbacks = false;
    }

    GlideTrace.endSectionAsync(TAG, cookie);
  }

//ImageViewTarget.java
 public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
    if (transition == null || !transition.transition(resource, this)) {
      setResourceInternal(resource);
    } else {
      maybeUpdateAnimatable(resource);
    }
  }
  
private void setResourceInternal(@Nullable Z resource) {
    // Order matters here. Set the resource first to make sure that the Drawable has a valid and
    // non-null Callback before starting it.
    setResource(resource);
    maybeUpdateAnimatable(resource);
  }
  
protected abstract void setResource(@Nullable Z resource);

还记得上面target的构造过程吗,ImageViewTarget有几个实现类,其中就是BitmapImageViewTarget和DrawableImageViewTarget,这里构建的是BitmapImageViewTarget, 我们看下setResource的实现

protected void setResource(Bitmap resource) {
    //最终调用View的setImageBitmap方法
    view.setImageBitmap(resource);
  }

如何感知生命周期

还记得前面RequestManager构造的时候有三种情况,context,FragmentActivity,Fragment。对于FragmentActivity,Fragment,构造的时候会分别传入activity.getLifecycle(),fragment.getLifecycle()。

RequestManager getOrCreate(
      Context context,
      Glide glide,
      final Lifecycle lifecycle,
      FragmentManager childFragmentManager,
      boolean isParentVisible) {
    Util.assertMainThread();
    RequestManager result = getOnly(lifecycle);
    if (result == null) {
      //先生成一个LifecycleLifecycle把上面传进来的Lifecycle作为参数
      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;
  }

LifecycleLifecycle比较简单,就是新建了一个Set lifecycleListeners,然后addListener的时候把传进来的LifecycleListener存储到lifecycleListeners里面。LifecycleLifecycle构造方法中会把本身绑定到Android系统的androidx.lifecycle.Lifecycle监听

final class LifecycleLifecycle implements Lifecycle, LifecycleObserver {
  @NonNull
  private final Set<LifecycleListener> lifecycleListeners = new HashSet<LifecycleListener>();

  @NonNull private final androidx.lifecycle.Lifecycle lifecycle;

  LifecycleLifecycle(androidx.lifecycle.Lifecycle lifecycle) {
    this.lifecycle = lifecycle;
    lifecycle.addObserver(this);
  }

  @OnLifecycleEvent(Event.ON_START)
  public void onStart(@NonNull LifecycleOwner owner) {
    //通知所有的LifecycleListener,Util.getSnapshot是为了线程安全,每次都copy出一份
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }

  @OnLifecycleEvent(Event.ON_STOP)
  public void onStop(@NonNull LifecycleOwner owner) {
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  @OnLifecycleEvent(Event.ON_DESTROY)
  public void onDestroy(@NonNull LifecycleOwner owner) {
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
    owner.getLifecycle().removeObserver(this);
  }

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

    if (lifecycle.getCurrentState() == State.DESTROYED) {
      listener.onDestroy();
    } else if (lifecycle.getCurrentState().isAtLeast(State.STARTED)) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

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

RequestManager(...) {
    ...
    if (Util.isOnBackgroundThread()) {
      Util.postOnUiThread(addSelfToLifecycle);
    } else {
      //这里将RequestManager实例添加到lifecycle的监听器集合中
      lifecycle.addListener(this);
    }
    ...
  }

如何监控网络变化

前面分析监控生命周期的时候,注意到一个connectivityMonitor也被添加到生命周期监控集合中

RequestManager(...) {
    ...
    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));
    ...
    
    //这里将connectivityMonitor添加到lifecycle的监听器集合中
    lifecycle.addListener(connectivityMonitor);
    ...
  }

ConnectivityMonitorFactory的实现只有一个DefaultConnectivityMonitorFactory,我们去看它的build方法

public class DefaultConnectivityMonitorFactory implements ConnectivityMonitorFactory {
  private static final String TAG = "ConnectivityMonitor";
  private static final String NETWORK_PERMISSION = "android.permission.ACCESS_NETWORK_STATE";

  @NonNull
  @Override
  public ConnectivityMonitor build(
      @NonNull Context context, @NonNull ConnectivityMonitor.ConnectivityListener listener) {
    int permissionResult = ContextCompat.checkSelfPermission(context, NETWORK_PERMISSION);
    boolean hasPermission = permissionResult == PackageManager.PERMISSION_GRANTED;
    ...
    return hasPermission
        ? new DefaultConnectivityMonitor(context, listener)
        : new NullConnectivityMonitor();
  }
}

这里主要新建了一个DefaultConnectivityMonitor,因为NullConnectivityMonitor是没有权限的时候才去新建的,方法都是空实现。

final class DefaultConnectivityMonitor implements ConnectivityMonitor {
  private final Context context;

  @SuppressWarnings("WeakerAccess")
  @Synthetic
  final ConnectivityListener listener;

  DefaultConnectivityMonitor(@NonNull Context context, @NonNull ConnectivityListener listener) {
    this.context = context.getApplicationContext();
    this.listener = listener;
  }

  private void register() {
    SingletonConnectivityReceiver.get(context).register(listener);
  }

  private void unregister() {
    SingletonConnectivityReceiver.get(context).unregister(listener);
  }

  @Override
  public void onStart() {
    register();
  }

  @Override
  public void onStop() {
    unregister();
  }

  @Override
  public void onDestroy() {
    // Do nothing.
  }
}

核心就是在onStart()注册一个监听,在onStop()取消注册监听。SingletonConnectivityReceiver是个单例模式实现的网络状态监听器。

final class SingletonConnectivityReceiver {
  private static volatile SingletonConnectivityReceiver instance;
  

  @GuardedBy("this")
  @Synthetic
  final Set<ConnectivityListener> listeners = new HashSet<ConnectivityListener>();

  //单例模式实现SingletonConnectivityReceiver
  static SingletonConnectivityReceiver get(@NonNull Context context) {
    if (instance == null) {
      synchronized (SingletonConnectivityReceiver.class) {
        if (instance == null) {
          instance = new SingletonConnectivityReceiver(context.getApplicationContext());
        }
      }
    }
    return instance;
  }


  private SingletonConnectivityReceiver(final @NonNull Context context) {
    GlideSupplier<ConnectivityManager> connectivityManager =
        GlideSuppliers.memorize(
            new GlideSupplier<ConnectivityManager>() {
              @Override
              public ConnectivityManager get() {
                return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
              }
            });
    ConnectivityListener connectivityListener =
        new ConnectivityListener() {
          @Override
          public void onConnectivityChanged(boolean isConnected) {
            //网络状态发生变化的时候通知所有的listeners
            Util.assertMainThread();
            List<ConnectivityListener> toNotify;
            synchronized (SingletonConnectivityReceiver.this) {
              toNotify = new ArrayList<>(listeners);
            }
            for (ConnectivityListener listener : toNotify) {
              listener.onConnectivityChanged(isConnected);
            }
          }
        };

    frameworkConnectivityMonitor =
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
            ? new FrameworkConnectivityMonitorPostApi24(connectivityManager, connectivityListener)
            : new FrameworkConnectivityMonitorPreApi24(
                context, connectivityManager, connectivityListener);
  }

  synchronized void register(ConnectivityListener listener) {
    listeners.add(listener);
    maybeRegisterReceiver();
  }

  /**
   * To avoid holding a lock while notifying listeners, the unregistered listener may still be
   * notified about a connectivity change after this method completes if this method is called on a
   * thread other than the main thread and if a connectivity broadcast is racing with this method.
   * Callers must handle this case.
   */
  synchronized void unregister(ConnectivityListener listener) {
    listeners.remove(listener);
    maybeUnregisterReceiver();
  }

  ...
}

用到哪些设计模式

  • 单例模式
  • 建造者模式
  • 外观模式
  • 享元模式
  • 原型模式
  • 观察者模式
  • 简单工厂
  • 工厂方法
  • 责任链模式
  • 策略模式

参考链接

https://juejin.cn/post/7044079102839488543?searchId=202410100927002AB04F7243D94B6586AA

https://blog.csdn.net/Love667767/article/details/106576888/

https://www.cnblogs.com/android-blogs/p/5735655.htmlun

相关推荐
尘浮生6 分钟前
Java项目实战II基于SpringBoot的客户关系管理系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·微信小程序·小程序
2401_857610038 分钟前
企业OA系统:Spring Boot技术实现与管理
java·spring boot·后端
飞滕人生TYF10 分钟前
java 集合 菱形内定义封装类 而非基本数据类型 原因解释 详解
java
繁依Fanyi13 分钟前
在 Spring Boot 中实现多种方式登录(用户名、手机号、邮箱等)的不正经指南
java·spring boot·后端
夕阳产业——JAVA,入坑=失业15 分钟前
泛型擦除是什么?
java·开发语言
legend_jz25 分钟前
【Linux】线程的互斥和同步
linux·运维·服务器·开发语言·笔记·学习·学习方法
ydl112826 分钟前
机器学习周志华学习笔记-第7章<贝叶斯分类器>
笔记·学习·机器学习
Gungnirss36 分钟前
前后端分离,后端拦截器无法获得前端请求的token
java·前端·token
codeMaster__hyd36 分钟前
使用IDEA构建springboot项目+整合Mybatis
java·linux·centos·intellij-idea·intellij idea·1024程序员节
l1384942745136 分钟前
Java综合练习
java·开发语言·算法