开源框架

Glide图片加载三步曲源码解析

2019-11-22  本文已影响0人  Steven_SHH

Glide图片加载框架大家都应该不会陌生,集成使用起来非常的简单,但是之前都没怎么看过Glide的源码,现在自己照着源码钻研一下,看看到底是如何通过这三个方法,就能加载出图片,做到这么强大的功能的。源码基于Glide4.9.0


Glide的基本使用

Glide最基本的使用方法就是三步,先with(),再load(),最后就是into(),然而就是这么三步简单的代码,就能将图片加载到我们的ImageView中,那么通过调用这三个方法到底是如何实现图片加载的呢?此次就对这个三个方法进行解析。

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

with()方法解析

@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 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);
}



// Glide中的getRetriever(Context)方法
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  ...// 会判断context不能为空,否者抛出异常
  // 通过Glide.get(context)获取或创建Glide单例对象
  // 通过glide对象获取RequestManagerRetriever对象
  return Glide.get(context).getRequestManagerRetriever();
}

由以上源码可以看出with()方法一共做了两件事


创建或获取Glide单例对象

// Glide中的get(Context)方法,获取线程安全的Glide单例对象
@NonNull
public static Glide get(@NonNull Context context) {
  if (glide == null) {
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context);
      }
    }
  }

  return glide;
}

// 检查Glide是否正在初始化,未在初始化则进行初始化
private static void checkAndInitializeGlide(@NonNull Context context) {
// 检查Glide是否正在初始化,保证Glide只被初始化一次
  if (isInitializing) {
    throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
        + " use the provided Glide instance instead");
  }
  isInitializing = true;
  initializeGlide(context);
  isInitializing = false;
}

// 初始化Glide
private static void initializeGlide(@NonNull Context context) {
  // 创建了一个GlideBuilder()实例传入initializeGlide()方法
  initializeGlide(context, new GlideBuilder());
}

// 初始化Glide
@SuppressWarnings("deprecation")
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
  Context applicationContext = context.getApplicationContext();
  // 获取@GlideModule注解驱动生成的GeneratedAppGlideModuleImpl和GeneratedAppGlideModuleFactory类
  GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
  List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
  if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
    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;
      }
      // ... 日志输出
      iterator.remove();
    }
  }

  // ... 日志输出

  // 尝试从注解生成的annotationGeneratedModule中获取RequestManager的构造工厂对象
  RequestManagerRetriever.RequestManagerFactory factory =
      annotationGeneratedModule != null
          ? annotationGeneratedModule.getRequestManagerFactory() : null;
  // 向GlideBuilder中设置管理器工厂
  builder.setRequestManagerFactory(factory);
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    module.applyOptions(applicationContext, builder);
  }
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.applyOptions(applicationContext, builder);
  }

  // 通过GlideBuilder中的build()方法创建Glide对象
  Glide glide = builder.build(applicationContext);
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    module.registerComponents(applicationContext, glide, glide.registry);
  }
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
  }
  applicationContext.registerComponentCallbacks(glide);
  // 给Glide对象赋值
  Glide.glide = glide;
}


可以看到通过GlideBuilder类中的build()方法创建Glide对象,并且保存在Glide类中的静态成员变量glide中


Glide对象的创建过程


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

  // 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(),
            GlideExecutor.newAnimationExecutor(),
            isActiveResourceRetentionAllowed);
  }

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

  // 创建了一个RequestManagerRetriever对象
  RequestManagerRetriever requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory);

  // 创建Glide对象
  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptions.lock(),
      defaultTransitionOptions,
      defaultRequestListeners,
      isLoggingRequestOriginsEnabled);
}


// Glide的构造方法
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 RequestOptions defaultRequestOptions,
    @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
    @NonNull List<RequestListener<Object>> defaultRequestListeners,
    boolean isLoggingRequestOriginsEnabled) {

  // 将GlideBuild中的管理引擎,线程池,缓存池等保存
  this.engine = engine;
  this.bitmapPool = bitmapPool;
  this.arrayPool = arrayPool;
  this.memoryCache = memoryCache;
  this.requestManagerRetriever = requestManagerRetriever;
  this.connectivityMonitorFactory = connectivityMonitorFactory;

  ...
  registry = new Registry();

  // 创建一个Registry,管理组件注册,以扩展或替换Glide的默认加载、解码和编码逻辑。
  ...

  // 创建一个GlideContext上下文
  glideContext =
      new GlideContext(
          context,
          arrayPool,
          registry,
          imageViewTargetFactory,
          defaultRequestOptions,
          defaultTransitionOptions,
          defaultRequestListeners,
          engine,
          isLoggingRequestOriginsEnabled,
          logLevel);
}

Glide的创建过程非常的复杂,构建了一系列的线程池,内存缓存策略,对象复用池,工厂类等,这里就不再进行深入探索。
在创建GlideBuilder.build的时候, 创建了一个RequestManagerRetriever对象并且传递到了Glide构造方法,并且进行保存,
于是通过Glide.getRequestManagerRetriever() 就可以获取到RequestManagerRetriever这个对象了


获取RequestManage对象

// 首先通过Glide对象获取RequestManagerRetriever对象
@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
  return requestManagerRetriever;
}


// 然后通过RequestManagerRetriever对象获取RequestManager对象(RequestManagerRetriever类中的方法) 
@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)) {
    // 判断当前线程是在主线程中并且传入的context不是ApplicationContext
    // 根据传入的context调用不同的get()方法
    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());
    }
  }

  // 如果是ApplicationContext直接调用getApplicationManager()方法获取RequestManager对象
  return getApplicationManager(context);
}


// 传入ApplicationContext获取RequestManager对象(RequestManagerRetriever类中的方法) 
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
  // 传入ApplicationContext或者在子线程时,会调用该方法创建或获取RequestManager对象
  if (applicationManager == null) {
    synchronized (this) {
      if (applicationManager == null) {
        Glide glide = Glide.get(context.getApplicationContext());
        // 通过RequestManagerFactory接口中的build方法,创建RequestManager对象...todo(没看到在哪里实现的)
        applicationManager =
            factory.build(
                glide,
                new ApplicationLifecycle(),
                new EmptyRequestManagerTreeNode(),
                context.getApplicationContext());
      }
    }
  }

  return applicationManager;
}

// 传入的context为FragmentActivity
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
  // 判断如果是子线程,则使用get(ApplicationContext)获取RequestManager对象
  if (Util.isOnBackgroundThread()) {
    return get(activity.getApplicationContext());
  } else {
    // 判断当前activity是否已经销毁,销毁会抛出异常
    assertNotDestroyed(activity);
    FragmentManager fm = activity.getSupportFragmentManager();
    // 通过supportFragmentGet方法获取RequestManager对象
    return supportFragmentGet(
        activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
  }
}

// 传入的context为Fragment
@NonNull
public RequestManager get(@NonNull 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());
  }
}

// 传入的context为Activity
@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));
  }
}


// 传入的context为View
@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(activity);
  }

  // Standard Fragments.
  android.app.Fragment fragment = findFragment(view, activity);
  if (fragment == null) {
    return get(activity);
  }
  return get(fragment);
}

// 判断当前activity是否已经销毁
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private static void assertNotDestroyed(@NonNull Activity activity) {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
    throw new IllegalArgumentException("You cannot start a load for a destroyed activity");
  }
}


// 通过supportFragmentGet方法获取RequestManager对象
@NonNull
private RequestManager supportFragmentGet(
    @NonNull Context context,
    @NonNull FragmentManager fm,
    @Nullable Fragment parentHint,
    boolean isParentVisible) {
  // 通过getSupportRequestManagerFragment方法创建一个隐藏的Fragment
  SupportRequestManagerFragment current =
      getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
  // 通过该fragment获取到RequestManager对象
  RequestManager requestManager = current.getRequestManager();
  if (requestManager == null) {
    // 如果requestManager对象为空,则通过RequestManagerFactory构建一个
    Glide glide = Glide.get(context);
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    // 将requestManager保存到当前fragment中
    current.setRequestManager(requestManager);
  }
  return requestManager;
}


@SuppressWarnings({"deprecation", "DeprecatedIsStillUsed"})
@Deprecated
@NonNull
private RequestManager fragmentGet(@NonNull Context context,
    @NonNull android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint,
    boolean isParentVisible) {
  //  从 Activity 中获取一个RequestManagerFragment, 用于监管Activity的声明周期
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
  // 获取Fragment中保存的当前页面的请求管理器 
  RequestManager requestManager = current.getRequestManager();
  // 不存在则创建一个请求管理器保存在RequestManagerFragment中
  if (requestManager == null) {
    Glide glide = Glide.get(context);
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}


// 创建一个隐藏的Fragment
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
    @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
  //  从FragmentManager中获取这个Fragment
  SupportRequestManagerFragment current =
      (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
  // 不存在则添加一个
  if (current == null) {
    // 从pendingSupportRequestManagerFragments中获取一个
    current = pendingSupportRequestManagerFragments.get(fm);
    if (current == null) {
      // 没有获取到则创建一个
      current = new SupportRequestManagerFragment();
      current.setParentFragmentHint(parentHint);
      if (isParentVisible) {
        current.getGlideLifecycle().onStart();
      }
      // 添加到等待被添加的缓存中
      pendingRequestManagerFragments.put(fm, current);
      // 因为添加到FragmentManager有延迟
      // 防止同一时间创建了两个RequestManagerFragment对象添加到Activity中
      pendingSupportRequestManagerFragments.put(fm, current);
      // 添加到FragmentManager中
      fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
      // 加到FragmentManager成功, 通过Handler移除这个缓存
      handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
    }
  }
  return current;
}

从源码中可以看到,RequestManagerRetriever.get()方法会判断Context的类型,根据传入不同的的类型,获取到不同RequestManager对象

传入Application类型的Context处理是比较简单的,因为Application对象的生命周期即应用程序的生命周期,因此Glide并不需要做什么特殊的处理,它自动就是和应用程序的生命周期是同步的,如果应用程序关闭的话,Glide的加载也会同时终止。

而非ApplictionContext则主要是在Activity页面中添加一个RequestManagerFragment实例, 以便用于监听Activity的生命周期, 然后给这个Fragment注入一个RequestManager。因为Glide并没有办法知道Activity的生命周期,所以采用这种添加隐藏Fragment的技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,当Activity被销毁后,Glide就能捕获到并且停止加载图片了。


load()方法解析

RequestManager类中load()方法同样很很多个重载方法,这里只列出常用的几个,会根据传入的参数类型调用RequestBuilder类中的不同的load()重载方法

//RequestManager类中的方法

@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable Bitmap bitmap) {
  // 通过调用asDrawable()方法,创建出一个RequestBuilder对象
  return asDrawable().load(bitmap);
}

@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable Drawable drawable) {
  return asDrawable().load(drawable);
}

@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable String string) {
  return asDrawable().load(string);
}


@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable File file) {
  return asDrawable().load(file);
}


@NonNull
@CheckResult
public RequestBuilder<Drawable> asDrawable() {
  // 全部都以Drawable类型传入as方法
  return as(Drawable.class);
}

@NonNull
@CheckResult
public <ResourceType> RequestBuilder<ResourceType> as(
    @NonNull Class<ResourceType> resourceClass) {
  // 创建出RequestBuilder对象
  return new RequestBuilder<>(glide, this, resourceClass, context);
}

其实load方法中,如果不去深究创建RequestBuilder对象的话,是非常简单的,所有重载方法都会先调用asDrawable()方法,传入Drawable类型,创建出RequestBuilder对象,然后再调用RequestBuilder中的load()方法


RequestBuilder

// RequestBuilder的构造方法
protected RequestBuilder(
    @NonNull Glide glide,
    RequestManager requestManager,
    Class<TranscodeType> transcodeClass,
    Context context) {
  this.glide = glide;
  this.requestManager = requestManager;
  this.transcodeClass = transcodeClass;
  this.context = context;
  this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
  this.glideContext = glide.getGlideContext();

  // 初始化requestManager中默认的请求监听
  initRequestListeners(requestManager.getDefaultRequestListeners());
  // 根据requestManager中的默认请求选项进行赋值,也就是我们经常用的占位图,错误图,缓存策略等选项
  apply(requestManager.getDefaultRequestOptions());
}


@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable Bitmap bitmap) {
  // 传入Bitmap时会设置不使用磁盘缓存
  return loadGeneric(bitmap)
      .apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable Drawable drawable) {
   // 传入Drawable时也会设置不使用磁盘缓存
  return loadGeneric(drawable)
      .apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}

@NonNull
@Override
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}

@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable File file) {
  return loadGeneric(file);
}

// 最终都会调用该方法
@NonNull
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
  this.model = model;
  // 标识是否已经调用了load()方法,在调用into()方法是会做判断,没有设置为true会抛出异常
  // 也就是在调用into()方法前,必须调用load()方法
  isModelSet = true;
  return this;
}

into()方法

@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
  // 判断是否在主线程中执行
  Util.assertMainThread();
  // 判空操作,view不能为空
  Preconditions.checkNotNull(view);

  // 根据view的scaleType重构RequestOptions
  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.
    }
  }

  // 调用into方法,创建执行请求
  return into(
      glideContext.buildImageViewTarget(view, transcodeClass),
      /*targetListener=*/ null,
      requestOptions,
      Executors.mainThreadExecutor());
}



private <Y extends Target<TranscodeType>> Y into(
    @NonNull Y target,
    @Nullable RequestListener<TranscodeType> targetListener,
    BaseRequestOptions<?> options,
    Executor callbackExecutor) {
  Preconditions.checkNotNull(target);
  // 调用into()方法之前 必须要先调用load()方法,isModelSet会在调用load方法之后赋值为true
  if (!isModelSet) {
    throw new IllegalArgumentException("You must call #load() before calling #into()");
  }

  // 调用buildRequest()方法,构建一个Request请求
  Request request = buildRequest(target, targetListener, options, callbackExecutor);

  Request previous = target.getRequest();
  if (request.isEquivalentTo(previous)
      && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
    request.recycle();
    if (!Preconditions.checkNotNull(previous).isRunning()) {
      previous.begin();
    }
    return target;
  }

  // 清除target之前的请求,释放资源
  requestManager.clear(target);
  //给ViewTarget设置这个Request请求,即Glide加载图片的请求
  target.setRequest(request);
  // 调用RequestManager.track()方法执行请求
  requestManager.track(target, request);

  return target;
}

可以看到into()方法的代码其实并不多,但是里面的涉及到的调用却嵌套了很多层,现在就一步一步的解析它里面调用的方法。


配置options

加载图片的时候会根据viewscaleType重构RequestOptions,所以先对这个进行解析,这里会根据不同的scaleType方式,调用不同的方法,
不过基本上差不多,这里选取其中的一种的requestOptions.clone().optionalFitCenter()进行解析

public abstract class BaseRequestOptions<T extends BaseRequestOptions<T>> implements Cloneable {

  @NonNull
  private Options options = new Options();
  @NonNull
  private Map<Class<?>, Transformation<?>> transformations = new CachedHashCodeArrayMap<>();

}

// clone方法,主要是对一些资源参数进行初始化赋值
public T clone() {
  try {
    BaseRequestOptions<?> result = (BaseRequestOptions<?>) super.clone();
    result.options = new Options();
    result.options.putAll(options);
    result.transformations = new CachedHashCodeArrayMap<>();
    result.transformations.putAll(transformations);
    result.isLocked = false;
    // 赋值不进行自动拷贝
    result.isAutoCloneEnabled = false;
    return (T) result;
  } catch (CloneNotSupportedException e) {
    throw new RuntimeException(e);
  }
}

public T optionalFitCenter() {
  // DownsampleStrategy描述降采样压缩的策略
  // FitCenter 描述图像变化方式
  return optionalScaleOnlyTransform(DownsampleStrategy.FIT_CENTER, new FitCenter());
}

private T optionalScaleOnlyTransform(
    @NonNull DownsampleStrategy strategy, @NonNull Transformation<Bitmap> transformation) {
  return scaleOnlyTransform(strategy, transformation, false /*isTransformationRequired*/);
}

private T scaleOnlyTransform(
    @NonNull DownsampleStrategy strategy,
    @NonNull Transformation<Bitmap> transformation,
    boolean isTransformationRequired) {
  // 这里根据传入的isTransformationRequired值,调用optionalTransform()方法
  BaseRequestOptions<T> result = isTransformationRequired
        ? transform(strategy, transformation) : optionalTransform(strategy, transformation);
  result.isScaleOnlyOrNoTransform = true;
  return (T) result;
}

final T optionalTransform(@NonNull DownsampleStrategy downsampleStrategy,
    @NonNull Transformation<Bitmap> transformation) {
  // 调用clone()方法时,赋值的false
  if (isAutoCloneEnabled) {
    return clone().optionalTransform(downsampleStrategy, transformation);
  }

  // 调用改方法,主要是保存options配置信息
  downsample(downsampleStrategy);
  return transform(transformation, /*isRequired=*/ false);
}

public T downsample(@NonNull DownsampleStrategy strategy) {
  return set(DownsampleStrategy.OPTION, Preconditions.checkNotNull(strategy));
}

public <Y> T set(@NonNull Option<Y> option, @NonNull Y value) {
  if (isAutoCloneEnabled) {
    return clone().set(option, value);
  }

  Preconditions.checkNotNull(option);
  Preconditions.checkNotNull(value);
  // 保存配置信息
  options.set(option, value);
  return selfOrThrowIfLocked();
}

T transform(
    @NonNull Transformation<Bitmap> transformation, boolean isRequired) {
  if (isAutoCloneEnabled) {
    return clone().transform(transformation, isRequired);
  }

  DrawableTransformation drawableTransformation =
      new DrawableTransformation(transformation, isRequired);
  // 调用了transform的重载方法, 将这个图像变化的方式作用到多种资源类型上
  transform(Bitmap.class, transformation, isRequired);
  transform(Drawable.class, drawableTransformation, isRequired);
  transform(BitmapDrawable.class, drawableTransformation.asBitmapDrawable(), isRequired);
  transform(GifDrawable.class, new GifDrawableTransformation(transformation), isRequired);
  return selfOrThrowIfLocked();
}

<Y> T transform(
    @NonNull Class<Y> resourceClass,
    @NonNull Transformation<Y> transformation,
    boolean isRequired) {
  if (isAutoCloneEnabled) {
    return clone().transform(resourceClass, transformation, isRequired);
  }

  Preconditions.checkNotNull(resourceClass);
  Preconditions.checkNotNull(transformation);

  // 添加到transformations缓存中
  transformations.put(resourceClass, transformation);

  fields |= TRANSFORMATION;
  isTransformationAllowed = true;
  fields |= TRANSFORMATION_ALLOWED;
  isScaleOnlyOrNoTransform = false;
  if (isRequired) {
    fields |= TRANSFORMATION_REQUIRED;
    isTransformationRequired = true;
  }
  return selfOrThrowIfLocked();
}

可以看到options配置操作,无非就是添加添加了图像变化操作, 并且设定采样方式, 分别保存在transformationsoptions


构建Target对象

可以看到最后调用into()方法时,调用了glideContext.buildImageViewTarget(view, transcodeClass)来构建Target对象

public class GlideContext extends ContextWrapper {
  public <X> ViewTarget<ImageView, X> buildImageViewTarget(
      @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
    return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
  }
}

public class ImageViewTargetFactory {
  @NonNull
  @SuppressWarnings("unchecked")
  public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
      @NonNull Class<Z> clazz) {
    //  根据目标编码的类型来创建不同的ViewTarget对象, 因为我们没有asBitmap, 因此这里为Drawable
    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)");
    }
  }
}

buildRequest创建Request

可以看到into()方法中,调用了buildRequest()方法来创建一个Request
Request request = buildRequest(target, targetListener, options, callbackExecutor);这里不具体去看到底是如何创建的,最终就是调用SingleRequest.obtain构建一个Request的实例对象

public class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>>
   implements Cloneable,
   ModelTypes<RequestBuilder<TranscodeType>> {

     private Request buildRequest(
     Target<TranscodeType> target,
     @Nullable RequestListener<TranscodeType> targetListener,
     BaseRequestOptions<?> requestOptions,
     Executor callbackExecutor) {
   return buildRequestRecursive(...);
 }

 // buildRequestRecursive方法中通过调用buildThumbnailRequestRecursive方法返回Request
 private Request buildRequestRecursive(
   Target<TranscodeType> target,
   @Nullable RequestListener<TranscodeType> targetListener,
   @Nullable RequestCoordinator parentCoordinator,
   TransitionOptions<?, ? super TranscodeType> transitionOptions,
   Priority priority,
   int overrideWidth,
   int overrideHeight,
   BaseRequestOptions<?> requestOptions,
   Executor callbackExecutor) {

 ...

 ErrorRequestCoordinator errorRequestCoordinator = null;
 if (errorBuilder != null) {
   errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
   parentCoordinator = errorRequestCoordinator;
 }

 Request mainRequest =
     buildThumbnailRequestRecursive(...);

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

 // 而该方法中通过obtainRequest创建Request
 private Request buildThumbnailRequestRecursive(
     Target<TranscodeType> target,
     RequestListener<TranscodeType> targetListener,
     @Nullable RequestCoordinator parentCoordinator,
     TransitionOptions<?, ? super TranscodeType> transitionOptions,
     Priority priority,
     int overrideWidth,
     int overrideHeight,
     BaseRequestOptions<?> requestOptions,
     Executor callbackExecutor) {

     ...

     // Base case: no thumbnail.
     return obtainRequest(...);
   
 }

 // 最终通过SingleRequest.obtain返回一个Request
 private Request obtainRequest(
     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(...);
 }

}

Request的分发

可以看到最后调用了requestManager.track(target, request);去分发请求,接下来我们就看看到底这个请求是如何进行分发的

public class RequestManager implements LifecycleListener,
  ModelTypes<RequestBuilder<Drawable>> {

  synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    // 将加载图片的Target保存到Set集合targets中
    targetTracker.track(target);
    // 执行请求
    requestTracker.runRequest(request);
  }

}

public final class TargetTracker implements LifecycleListener {
  private final Set<Target<?>> targets =
      Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());

  public void track(@NonNull Target<?> target) {
    targets.add(target);
  }
 } 


public class RequestTracker {

  public void runRequest(@NonNull Request request) {
    requests.add(request);
    if (!isPaused) {
      // 开始执行任务
      request.begin();
    } else {
      request.clear();
      pendingRequests.add(request);
    }
  }

}


public final class SingleRequest<R> implements Request,
    SizeReadyCallback,
    ResourceCallback,
    FactoryPools.Poolable {

  @Override
  public synchronized void begin() {

    ...
    // 正在运行
    if (status == Status.RUNNING) {
      throw new IllegalArgumentException("Cannot restart a running request");
    }

    // 资源已经加载完成
    if (status == Status.COMPLETE) {
      onResourceReady(resource, DataSource.MEMORY_CACHE);
      return;
    }
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      // 表示尺寸已经准备好了
      onSizeReady(overrideWidth, overrideHeight);
    } else {
      target.getSize(this);
    }

    if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
        && canNotifyStatusChanged()) {
      target.onLoadStarted(getPlaceholderDrawable());
    }

  }


@Override
public synchronized void onSizeReady(int width, int height) {
  stateVerifier.throwIfRecycled();
  
  if (status != Status.WAITING_FOR_SIZE) {
    return;
  }
  // 标识正在运行的状态
  status = Status.RUNNING;

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

  // 调用engine.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);

  if (status != Status.RUNNING) {
    loadStatus = null;
  }
  if (IS_VERBOSE_LOGGABLE) {
    logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
  }
}

}

任务的创建engine.load()

在尺寸准备好后,就会在onSizeReady中调用engine.load()去构建任务

public class Engine implements EngineJobListener,
    MemoryCache.ResourceRemovedListener,
    EngineResource.ResourceListener {

  public synchronized <R> LoadStatus load(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class<?> resourceClass,
      Class<R> transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map<Class<?>, Transformation<?>> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      Options options,
      boolean isMemoryCacheable,
      boolean useUnlimitedSourceExecutorPool,
      boolean useAnimationPool,
      boolean onlyRetrieveFromCache,
      ResourceCallback cb,
      Executor callbackExecutor) {
   
    // 根据传入的参数, 构建这个请求的 key
    EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
        resourceClass, transcodeClass, options); 
               
    // 从ActiveResources中查找key对应的资源
    EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
    if (active != null) {
      // 若存在, 则直接回调onResourceReady处理后续操作
      cb.onResourceReady(active, DataSource.MEMORY_CACHE);
      return null;
    }

    // 从缓存中查找key对应的资源
    EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
    if (cached != null) {
      // 若缓存存在, 则直接回调onResourceReady处理后续操作
      cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
      return null;
    }

    // 查找key对应的任务
    EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
    if (current != null) {
      // 如果存在,说明这个任务已经正在执行了, 无需再次构建执行
      current.addCallback(cb, callbackExecutor);
      // 返回加载的状态
      return new LoadStatus(cb, current);
    }

    // 构建一个新的任务
    EngineJob<R> engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);
    
    // 构建解码任务
    DecodeJob<R> decodeJob =
        decodeJobFactory.build(
            glideContext,
            model,
            key,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            onlyRetrieveFromCache,
            options,
            engineJob);

    // 保存该任务
    jobs.put(key, engineJob);

    engineJob.addCallback(cb, callbackExecutor);
    // 执行任务
    engineJob.start(decodeJob);

    return new LoadStatus(cb, engineJob);
  }
}

可以看到Engine.load中的事情非常的重要


任务的执行

class EngineJob<R> implements DecodeJob.Callback<R>,
    Poolable {
    
  private final GlideExecutor diskCacheExecutor;  
  private DecodeJob<R> decodeJob;

  public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    // 获取线程池
    GlideExecutor executor = decodeJob.willDecodeFromCache()
        ? diskCacheExecutor : getActiveSourceExecutor();
    // 执行任务
    executor.execute(decodeJob);
  }
  
}

class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable<DecodeJob<?>>,
    Poolable {
    
  @Override      
  public void run() {
     try {
      ......
      // 调用了 runWrapped
      runWrapped();
    } catch (CallbackException e) {
      ......
    }
  }        
  
  private void runWrapped() {
    switch (runReason) {
      case INITIALIZE:
        // 1. 获取任务的场景
        stage = getNextStage(Stage.INITIALIZE);
        // 2. 获取这个场景的执行者
        currentGenerator = getNextGenerator();
        // 3. 执行者执行任务
        runGenerators();
        break;
      ......
    }
  }
  
  private Stage getNextStage(Stage current) {
    switch (current) {
      case INITIALIZE:
        // 1.1 若我们配置的缓存策略允许从资源缓存中读数据, 则返回Stage.RESOURCE_CACHE
        return diskCacheStrategy.decodeCachedResource()
            ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
      case RESOURCE_CACHE:
        // 1.2 若我们配置的缓存策略允许从源数据缓存中读数据, 则返回 Stage.DATA_CACHE
        return diskCacheStrategy.decodeCachedData()
            ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
      case DATA_CACHE:
        // 1.3 若只能允许从缓存中获取数据, 则直接FINISH, 否则返回Stage.SOURCE, 意为加载一个新的资源
        return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
      case SOURCE:
      case FINISHED:
        return Stage.FINISHED;
      default:
        throw new IllegalArgumentException("Unrecognized stage: " + current);
    }
  }
  
  private DataFetcherGenerator getNextGenerator() {
    switch (stage) {
      case RESOURCE_CACHE:
        // 资源磁盘缓存的执行者
        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 void runGenerators() {
    ......
    boolean isStarted = false;
    // 调用 DataFetcherGenerator.startNext() 执行了请求操作
    while (!isCancelled && currentGenerator != null
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();
      if (stage == Stage.SOURCE) {
        reschedule();
        return;
      }
    }
    ......
  }
}


获取数据源

class SourceGenerator implements DataFetcherGenerator,
    DataFetcher.DataCallback<Object>,
    DataFetcherGenerator.FetcherReadyCallback {
  
  private final DecodeHelper<?> helper;
  
  public boolean startNext() {
    ......
    loadData = null;
    boolean started = false;
    while (!started && hasNextModelLoader()) {
      // 1. 从 DecodeHelper 的数据加载集合中, 获取一个数据加载器
      loadData = helper.getLoadData().get(loadDataListIndex++);
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
          || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
        // 2. 使用加载器中 fetcher 执行数据加载
        loadData.fetcher.loadData(helper.getPriority(), this);
      }
    }
    return started;
  } 
}

SourceGenerator主要有两步

获取数据加载器

final class DecodeHelper<Transcode> {
    
  private final List<LoadData<?>> loadData = new ArrayList<>();
  private GlideContext glideContext;
  private Object model;
  private boolean isLoadDataSet;    
  
  List<LoadData<?>> getLoadData() {
    if (!isLoadDataSet) {
      isLoadDataSet = true;
      loadData.clear();
      // 1. 从 Glide 注册的 register 中获取请求 model 加载器
      List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
      // 遍历每一个 modelLoaders 
      for (int i = 0, size = modelLoaders.size(); i < size; i++) {
        // 2. 通过 modelLoaders 构建 loadData
        ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
        LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
        if (current != null) {
          // 添加到缓存
          loadData.add(current);
        }
      }
    }
    return loadData;
  }  
    
}

它会找到一个ModelLoader的实现类, 通过这个实现类的handles方法, 判断是否可以加载这个model
这里我们的model以网络的URL资源举例, 它的实现类为HttpGlideUrlLoader我们看看它如何构建一个 LoadData对象的

public class HttpGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {
  
  @Nullable private final ModelCache<GlideUrl, GlideUrl> modelCache;
  
  @Override
  public LoadData<InputStream> buildLoadData(@NonNull GlideUrl model, int width, int height,
      @NonNull Options options) {  
    GlideUrl url = model;
    .....
    int timeout = options.get(TIMEOUT);
    // 创建了一个 LoadData 对象, 并且实例化了一个 HttpUrlFetcher 给它
    return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
  }
    
}

对于URL的加载, 其fetcher为一个HttpUrlFetcher的实例

执行数据加载

获取到了数据加载器之后, SourceGeneratorstartNext中便会调用其fetcherloadData执行数据的加载了

public class HttpUrlFetcher implements DataFetcher<InputStream> {
    
  public void loadData(@NonNull Priority priority,
      @NonNull DataCallback<? super InputStream> callback) {
    long startTime = LogTime.getLogTime();
    try {
      // 获取网络图片, 内部使用了 HttpConnection 实现, 仅仅做了重定向的处理
      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
      // 将 inputStream 回调出去
      callback.onDataReady(result);
    } catch (IOException e) {
      ......
      callback.onLoadFailed(e);
    } finally {
      ......
    }
  }
    
}

HttpUrlFetcher它使用了HttpConnection发起了网络请求, 获取了数据流, 至此数据资源的获取就已经完成了, 后面要做的便是最重要的数据处理了, 它通过回调的方式将InputStream扔了出去, 最终会回溯到 DecodeJobonDataFetcherReady这个方法中

数据源的处理

class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable<DecodeJob<?>>,
    Poolable {

  private Key currentSourceKey;
  private Object currentData;
  private DataSource currentDataSource;
  private DataFetcher<?> currentFetcher;

  @Override
  public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
      DataSource dataSource, Key attemptedKey) {
    this.currentSourceKey = sourceKey;  // 保存数据的 key
    this.currentData = data;            // 保存数据实体
    this.currentFetcher = fetcher;      // 保存数据的获取器
    this.currentDataSource = dataSource;// 数据来源: url 为 REMOTE 类型的枚举, 表示从远程获取
    ......
    if (Thread.currentThread() != currentThread) {
      ......
    } else {
      try {
        // 调用 decodeFromRetrievedData 解析获取的数据
        decodeFromRetrievedData();
      } finally {
        ......
      }
    }
  }

  private void decodeFromRetrievedData() {
    Resource<R> resource = null;
    try {
      // 1\. 调用了 decodeFromData 获取资源
      resource = decodeFromData(/*HttpUrlFetcher*/currentFetcher, /*InputStream*/currentData,/*REMOTE*/ currentDataSource);
    } catch (GlideException e) {
      ......
    }
    if (resource != null) {
      // 2\. 通知外界资源获取成功了
      notifyEncodeAndRelease(resource, currentDataSource);
    } else {
      ......
    }
  }
}

可以看到对于获取到的数据, 首先要将其解码为Resource类型的资源, 然后再将资源返回给上层
我们先看看它是如何将数据解析成 Resource(非Android系统的Resource) 资源的


资源的获取

class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable<DecodeJob<?>>,
    Poolable {

  private <Data> Resource<R> decodeFromData(DataFetcher<?> fetcher, Data data,
      DataSource dataSource) throws GlideException {
    try {
      ......
      // 调用了 decodeFromFetcher
      Resource<R> result = decodeFromFetcher(data, dataSource);
      ......
      return result;
    } finally {
    }
  }

  private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
      throws GlideException {
    // 1. 获取当前数据类的解析器 LoadPath
    LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
    // 2. 通过解析器来解析来解析数据
    return runLoadPath(data, dataSource, path);
  }

  private <Data, ResourceType> Resource<R> runLoadPath(Data data, DataSource dataSource,
      LoadPath<Data, ResourceType, R> path) throws GlideException {
    Options options = getOptionsWithHardwareConfig(dataSource);
    // 2.1 根据数据类型获取一个数据重造器, 获取的数据为 InputStream, 因此它是一个 InputStreamRewinder 的实例
    DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
    try {
      // 2.2 将解析资源的任务转移到了 LoadPath.load 方法中
      return path.load( rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
    } finally {
      rewinder.cleanup();
    }
  }        
}

可以看到为了解析数据, 首先构建了一个LoadPath, 然后创建了一个InputStreamRewinder类型的 DataRewinder, 最终将数据解析的操作到了LoadPath.load方法中


接下来看看这个LoadPath.load 做了哪些处理

public class LoadPath<Data, ResourceType, Transcode> {

 public Resource<Transcode> load(DataRewinder<Data> rewinder, @NonNull Options options, int width,
      int height, DecodePath.DecodeCallback<ResourceType> decodeCallback) throws GlideException {
    ......
    try {
      return loadWithExceptionList(rewinder, options, width, height, decodeCallback, throwables);
    } finally {
      ......
    }
  }

  private final List<? extends DecodePath<Data, ResourceType, Transcode>> decodePaths;

  private Resource<Transcode> loadWithExceptionList(DataRewinder<Data> rewinder,
      @NonNull Options options, int width, int height, DecodePath.DecodeCallback<ResourceType> decodeCallback,
      List<Throwable> exceptions) throws GlideException {
    Resource<Transcode> result = null;
    // 遍历内部存储的 DecodePath 集合, 通过他们来解析数据
    for (int i = 0, size = decodePaths.size(); i < size; i++) {
      DecodePath<Data, ResourceType, Transcode> path = decodePaths.get(i);
      try {
        // 调用 DecodePath.decode 真正进行数据的解析
        result = path.decode(rewinder, width, height, options, decodeCallback);
      } catch (GlideException e) {
        ......
      }
      ......
    }
    return result;
  }

}

public class DecodePath<DataType, ResourceType, Transcode> {

  public Resource<Transcode> decode(DataRewinder<DataType> rewinder, int width, int height,
      @NonNull Options options, DecodeCallback<ResourceType> callback) throws GlideException {
    // 1\. 调用 decodeResource 将源数据解析成中间资源
    Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options);
    // 2\. 调用 DecodeCallback.onResourceDecoded 处理中间资源
    Resource<ResourceType> transformed = callback.onResourceDecoded(decoded);
    // 3\. 调用 ResourceTranscoder.transcode 将中间资源转为目标资源
    return transcoder.transcode(transformed, options);
  }

  private Resource<ResourceType> decodeResource(DataRewinder<DataType> rewinder, int width,
      int height, @NonNull Options options) throws GlideException {
    try {
      // 1.1 调用了 decodeResourceWithList
      return decodeResourceWithList(rewinder, width, height, options, exceptions);
    } finally {
      ......
    }
  }

  @NonNull
  private Resource<ResourceType> decodeResourceWithList(DataRewinder<DataType> rewinder, int width,
      int height, @NonNull Options options, List<Throwable> exceptions) throws GlideException {
    Resource<ResourceType> result = null;
    for (int i = 0, size = decoders.size(); i < size; i++) {
      ResourceDecoder<DataType, ResourceType> decoder = decoders.get(i);
      try {
        DataType data = rewinder.rewindAndGet();
        if (decoder.handles(data, options)) {
          data = rewinder.rewindAndGet();
          // 1.2 调用 ResourceDecoder.decode 解析源数据
          result = decoder.decode(data, width, height, options);
        }
      } 
      ......
      if (result != null) {
        break;
      }
    }
    return result;
  }

}

可以看到数据解析的任务最重是通过DecodePath来执行的, 它内部有三个操作


解析源数据

因为本次流程的源数据为InputStream因此它的解析器为StreamBitmapDecoder

public class StreamBitmapDecoder implements ResourceDecoder<InputStream, Bitmap> {

  private final Downsampler downsampler;

  public Resource<Bitmap> decode(@NonNull InputStream source, int width, int height,
      @NonNull Options options)
      throws IOException {
    ......
    try {
      // 根据请求配置的数据, 对数据流进行采样压缩, 获取到一个 Resource<Bitmap>
      return downsampler.decode(invalidatingStream, width, height, options, callbacks);
    } finally {
      ......
    }
  }

}

可以看到它内部通过Downsampler.decode方法对数据流进行采样压缩, 来获取这个流的Bitmap

获取到了Resource之后, 又是如何处理这个资源的呢?


资源的处理

当我们将源数据解析成对应的资源之后, 便会调用DecodeCallback.onResourceDecoded处理资源

class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable<DecodeJob<?>>,
    Poolable {

  private final class DecodeCallback<Z> implements DecodePath.DecodeCallback<Z> {

    @Override
    public Resource<Z> onResourceDecoded(@NonNull Resource<Z> decoded) {
      // 调用了外部类的 onResourceDecoded 方法
      return DecodeJob.this.onResourceDecoded(dataSource, decoded);
    }

  }

  private final DeferredEncodeManager<?> deferredEncodeManager = new DeferredEncodeManager<>();

  <Z> Resource<Z> onResourceDecoded(DataSource dataSource,
      @NonNull Resource<Z> decoded) {
    // 1. 获取数据资源的类型
    Class<Z> resourceSubClass = (Class<Z>) decoded.get().getClass();
    Transformation<Z> appliedTransformation = null;
    Resource<Z> transformed = decoded;

    // 2. 若非从资源磁盘缓存中获取的数据源, 则对资源进行 transformation 操作
    if (dataSource != DataSource.RESOURCE_DISK_CACHE) {
      appliedTransformation = decodeHelper.getTransformation(resourceSubClass);
      transformed = appliedTransformation.transform(glideContext, decoded, width, height);
    }
    ......
    // 3. 构建数据编码的策略
    final EncodeStrategy encodeStrategy;
    final ResourceEncoder<Z> encoder;
    if (decodeHelper.isResourceEncoderAvailable(transformed)) {
      encoder = decodeHelper.getResultEncoder(transformed);
      encodeStrategy = encoder.getEncodeStrategy(options);
    } else {
      encoder = null;
      encodeStrategy = EncodeStrategy.NONE;
    }
    // 4 根据编码策略, 构建缓存的 key
    Resource<Z> result = transformed;
    boolean isFromAlternateCacheKey = !decodeHelper.isSourceKey(currentSourceKey);
    if (diskCacheStrategy.isResourceCacheable(isFromAlternateCacheKey, dataSource,
        encodeStrategy)) {
      ......
      final Key key;
      switch (encodeStrategy) {
        case SOURCE:
          // 源数据的 key
          key = new DataCacheKey(currentSourceKey, signature);
          break;
        case TRANSFORMED:
          // 资源数据的 key
          key =
              new ResourceCacheKey(......);
          break;
        default:
          throw new IllegalArgumentException("Unknown strategy: " + encodeStrategy);
      }
      // 5. 初始化编码管理者, 用于提交内存缓存
      LockedResource<Z> lockedResult = LockedResource.obtain(transformed);
      deferredEncodeManager.init(key, encoder, lockedResult);
      result = lockedResult;
    }
    // 返回 transform 之后的 bitmap
    return result;
  }

}

可以看到onResourceDecoded中, 主要是对中间资源做了如下的操作

好的, 这个方法执行结束之后, 这个资源就与我们期望的效果一致了, 接下来只需要将它转为目标格式就可以展示了


将数据转为目标格式

目标数据为Drawable, 因此它的转换器为BitmapDrawableTranscoder

public class BitmapDrawableTranscoder implements ResourceTranscoder<Bitmap, BitmapDrawable> {

  private final Resources resources;

  @Nullable
  @Override
  public Resource<BitmapDrawable> transcode(@NonNull Resource<Bitmap> toTranscode,
      @NonNull Options options) {
    // 调用了 LazyBitmapDrawableResource.obtain 获取 Resource<BitmapDrawable> 的实例对象
    return LazyBitmapDrawableResource.obtain(resources, toTranscode);
  }

}

public final class LazyBitmapDrawableResource implements Resource<BitmapDrawable>,
    Initializable {

  public static Resource<BitmapDrawable> obtain(
      @NonNull Resources resources, @Nullable Resource<Bitmap> bitmapResource) {
    ......
    // 创建了一个 LazyBitmapDrawableResource
    return new LazyBitmapDrawableResource(resources, bitmapResource);
  }

  private LazyBitmapDrawableResource(@NonNull Resources resources,
      @NonNull Resource<Bitmap> bitmapResource) {
    this.resources = Preconditions.checkNotNull(resources);
    this.bitmapResource = Preconditions.checkNotNull(bitmapResource);
  }

  public BitmapDrawable get() {
    // Get 方法反回了一个 BitmapDrawable 对象
    return new BitmapDrawable(resources, bitmapResource.get());
  }

}

转化成目标数据也比较的简单, 它将我们解析到的bitmap存放到LazyBitmapDrawableResource内部, 然后外界通过get方法就可以获取到一个BitmapDrawable的对象了


数据的展示

class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable<DecodeJob<?>>,
    Poolable {

  private void decodeFromRetrievedData() {
    Resource<R> resource = null;
    ......// 解析 inputStream 获取资源 
    if (resource != null) {
      // 通知外界资源获取成功了
      notifyEncodeAndRelease(resource, currentDataSource);
    } else {
      ......
    }
  }

  private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
    ......
    // 1. 回调上层资源准备好了
    notifyComplete(result, dataSource);
    ......
    try {
      // 2. 将数据缓存到磁盘
      if (deferredEncodeManager.hasResourceToEncode()) {
        deferredEncodeManager.encode(diskCacheProvider, options);
      }
    } finally {
      ...
    }
  }

  private Callback<R> callback;

  private void notifyComplete(Resource<R> resource, DataSource dataSource) {
    ......
    // 1.1 从 DecodeJob 的构建中, 我们知道这个 Callback 是一 EngineJob
    callback.onResourceReady(resource, dataSource);
  }

}

可以看到DecodeJob.decodeFromRetrievedData中, 主要做了两个操作


磁盘缓存并非我们关注的终点, 这里我们看看EngineJob.onResourceReady中做了哪些处理

class EngineJob<R> implements DecodeJob.Callback<R>,
    Poolable {

  @Override
  public void onResourceReady(Resource<R> resource, DataSource dataSource) {
    synchronized (this) {
      this.resource = resource;
      this.dataSource = dataSource;
    }
    notifyCallbacksOfResult();
  } 

  void notifyCallbacksOfResult() {
    ResourceCallbacksAndExecutors copy;
    Key localKey;
    EngineResource<?> localResource;
    synchronized (this) {
      ......
      engineResource = engineResourceFactory.build(resource, isCacheable);
      hasResource = true;
      copy = cbs.copy();
      incrementPendingCallbacks(copy.size() + 1);

      localKey = key;
      localResource = engineResource;
    }
    // 1. 通知上层 Engine 任务完成了
    listener.onEngineJobComplete(this, localKey, localResource);
    // 2. 回调给 ImageViewTarget 展示资源
    for (final ResourceCallbackAndExecutor entry : copy) {
      entry.executor.execute(new CallResourceReady(entry.cb));
    }
  }

}

EngineJob中也是有两步操作, 一个是通知上层任务完成了, 另一个是回调给ImageViewTarget展示资源


我们先看看上层做了什么处理

public class Engine implements EngineJobListener,
    MemoryCache.ResourceRemovedListener,
    EngineResource.ResourceListener {

  public synchronized void onEngineJobComplete(
      EngineJob<?> engineJob, Key key, EngineResource<?> resource) {
    if (resource != null) {
      // 将加载好的资源添加到内存缓存
      if (resource.isCacheable()) {
        activeResources.activate(key, resource);
      }
    }
    ......
  }

}

我们知道在请求发起前是Engine尝试通过内存缓存读, 结束之后再回到Engine添加内存缓存也不足为奇了

接下来我们看看ImageViewTarget展示资源的过程

public abstract class ImageViewTarget<Z> extends ViewTarget<ImageView, Z>
    implements Transition.ViewAdapter {

  public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
    // 处理一些 transition 变化, 在构建 Request 时有分析过, 这里不赘述其实现细节了
    if (transition == null || !transition.transition(resource, this)) {
      setResourceInternal(resource);
    } else {
      ......
    }
  }

  private void setResourceInternal(@Nullable Z resource) {
    // 调用了 setResource
    setResource(resource);
    ......
  }

}

public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {

  protected void setResource(@Nullable Drawable resource) {
    // 呈现到 View 上
    view.setImageDrawable(resource);
  }  

}

ImageViewTarget调用了子类重写的setResource方法, 将数据填充进去, 至此一次Glide图像加载就完成了

总结

通过一次流程分析我们得知, 整个Glide图片加载主要有如下几步

Glide的源码还是真的有点复杂,这还只是最简单的流程,都给我看蒙了,可想而知他内部代码逻辑有多复杂。

上一篇 下一篇

猜你喜欢

热点阅读