Glide加载图片流程

glide源码精髓是能学习到很多设计模式,以及对图片的各种处理,首先以源码通读的方式进入到今天的文章。

glide源码是在4.16.0的版本上分析的。 平常我们使用glide时候直接glide.with(activity).load(url).into(imageview)加载图片,基于此,我们顺藤摸瓜看下底层是怎么加载图片的。

Glide.with

我们是基于参数是activity的重载方法:

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

先获取RequestManagerRetriever,然后再获取RequestManager:

1
2
3
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  return Glide.get(context).getRequestManagerRetriever();
}

首先调用Glide.get(context)方法,然后通过getRequestManagerRetriever方法获取到RequestManagerRetriever:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public static Glide get(@NonNull Context context) {
  if (glide == null) {
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context);
      }
    }
  }
  return glide;
}

可以看到该方法是一个静态方法加锁,锁的是所有线程创建glide的实例。如果glide为空,会调用checkAndInitializeGlide方法,猜测是创建glide实例的方法: alt text
此处不允许多次初始化glide对象,通过一个布尔值控制,并且该布尔值是一个volatile类型的,在多线程中访问是安全的。接着调用了initializeGlide方法:

1
2
3
4
private static void initializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

调用了另外一个initializeGlide方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
private static void initializeGlide(
    @NonNull Context context,
    @NonNull GlideBuilder builder,
    @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    //省略代码
  Context applicationContext = context.getApplicationContext();
  Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
  applicationContext.registerComponentCallbacks(glide);
  Glide.glide = glide;
}

此处省略了通过注解来生成各种配置,其中注解是GlideModule的注解,它是一个编译时注解,通过编译时扫描到该注解,然后生成GeneratedAppGlideModuleImpl类,initializeGlide是通过反射执行GeneratedAppGlideModuleImpl类。最终通过GlideBuilder.build方法来生成glide对象:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Glide build(@NonNull Context context) {
  if (sourceExecutor == null) {//访问资源的线程池
    sourceExecutor = GlideExecutor.newSourceExecutor();
  }
  if (diskCacheExecutor == null) {//缓存线程池
    diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
  }
  if (animationExecutor == null) {//动画线程池
    animationExecutor = GlideExecutor.newAnimationExecutor();
  }
  if (memorySizeCalculator == null) {
    memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
  }
  if (connectivityMonitorFactory == null) {
    connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
  }
  if (bitmapPool == null) {
    int size = memorySizeCalculator.getBitmapPoolSize();
    if (size > 0) {
      bitmapPool = new LruBitmapPool(size);
    } else {
      bitmapPool = new BitmapPoolAdapter();
    }
  }
  if (arrayPool == null) {
    arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
  }
  if (memoryCache == null) {
    memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
  }
  if (diskCacheFactory == null) {
    diskCacheFactory = new InternalCacheDiskCacheFactory(context);
  }
  if (engine == null) {
    engine =
        new Engine(
            memoryCache,
            diskCacheFactory,
            diskCacheExecutor,
            sourceExecutor,
            GlideExecutor.newUnlimitedSourceExecutor(),
            GlideExecutor.newAnimationExecutor(),
            isActiveResourceRetentionAllowed);
  }
  RequestManagerRetriever requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory);
  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptions.lock(),
      defaultTransitionOptions);
}

初始化线程池,构造了Engine、RequestManagerRetriever对象,最后初始化了Glide对象。所以上面的getRequestManagerRetriever方法返回的对象就是此处new的RequestManagerRetriever对象。接着调用了RequestManagerRetriever的get方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@NonNull
public RequestManager get(@NonNull Context context) {
  if (context == null) {
    throw new IllegalArgumentException("You cannot start a load on a null Context");
  } else if (Util.isOnMainThread() && !(context instanceof Application)) {
    if (context instanceof FragmentActivity) {
      return get((FragmentActivity) context);
    } else if (context instanceof ContextWrapper
        && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
      return get(((ContextWrapper) context).getBaseContext());
    }
  }
  return getApplicationManager(context);
}

该方法会返回一个RequestManager对象,如果context不是Application类型,则通过get方法创建RequestManager对象,如果是Application类型,则通过getApplicationManager方法创建。首先来看下通过FragmentActivity来创建RequestManager对象:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public RequestManager get(@NonNull FragmentActivity activity) {
  //如果当前不是主线程,则通过Application创建
  if (Util.isOnBackgroundThread()) {
    return get(activity.getApplicationContext());
  }
  assertNotDestroyed(activity);
  frameWaiter.registerSelf(activity);
  boolean isActivityVisible = isActivityVisible(activity);
  Glide glide = Glide.get(activity.getApplicationContext());
  return lifecycleRequestManagerRetriever.getOrCreate(
      activity,
      glide,
      activity.getLifecycle(),
      activity.getSupportFragmentManager(),
      isActivityVisible);
}

首先判断当前线程如果不是主线程,则通过Application创建RequestManager,接着判断activity是否可见,可见的条件是activity没有finish掉。最终通过LifecycleRequestManagerRetriever的getOrCreate方法来创建RequestManager:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
RequestManager getOrCreate(
    Context context,
    Glide glide,
    final Lifecycle lifecycle,
    FragmentManager childFragmentManager,
    boolean isParentVisible) {
  Util.assertMainThread();
  RequestManager result = getOnly(lifecycle);
  if (result == null) {
    LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
    result =
        factory.build(
            glide,
            glideLifecycle,
            new SupportRequestManagerTreeNode(childFragmentManager),
            context);
    lifecycleToRequestManager.put(lifecycle, result);
    glideLifecycle.addListener(
        new LifecycleListener() {
          @Override
          public void onStart() {}

          @Override
          public void onStop() {}

          @Override
          public void onDestroy() {
            lifecycleToRequestManager.remove(lifecycle);
          }
        });
    if (isParentVisible) {
      result.onStart();
    }
  }
  return result;
}

先通过getOnly从lifecycleToRequestManager这个map中取,key是activity的lifecycle对象,如果没有取到则通过factory.build来创建RequestManager,factory是RequestManagerFactory接口,它是在glide初始化的时候构造的。LifecycleRequestManagerRetriever中的factory是在RequestManagerRetriever构造方法中传进来的:

1
2
3
4
5
public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
  this.factory = factory != null ? factory : DEFAULT_FACTORY;
  lifecycleRequestManagerRetriever = new LifecycleRequestManagerRetriever(this.factory);
  frameWaiter = buildFrameWaiter();
}

RequestManagerRetriever构造方法中默认传入的RequestManagerFactory是空的,因此会用DEFAULT_FACTORY:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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) {
        return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
      }
    };

直接new了一个RequestManager对象,可见典型的工厂模式创建对象。

  • 小结
    • Glide.with方法里面判断glide单例对象是否存在,如果不存在先在GlideBuilder的build方法中创建各种线程池,包括访问资源的线程池,缓存线程池,动画线程池等。然后创建Engine和RequestManagerRetriever对象,接着把创建的各种线程池,pool,Engine和RequestManagerRetriever都传入到Glide对象中,方便后面使用。上面在构建Glide之前会判断GeneratedAppGlideModule注解的类存不存在,它是通过注解来配置各种参数的类。
    • 构建完Glide对象后,接着通过RequestManagerRetriever的get方法创建RequestManager,其中创建RequestManager的方式有Application,Fragment,Activity的形式,我们拿Activity的形式创建来说,如果当前线程不是主线程,则使用Application的形式来创建,因为非主线程是不带生命周期。接着通过LifecycleRequestManagerRetriever的getOrCreate方法来获取RequestManager,此处的LifecycleRequestManagerRetriever是在RequestManagerRetriever构造方法中创建的。
    • LifecycleRequestManagerRetriever的getOrCreate方法中通过map存储了Lifecycle中的RequestManager,也就是说每一个Lifecycle对应一个RequestManager。首先判断该map中是否存在RequestManager,如果不存在,创建了一个LifecycleLifecycle,它是一个LifecycleObserver对象,它通过监听Activity等类型的Lifecycle的生命周期,来管理Lifecycle和RequestManager。
    • 上面就是整个Glide.with创建RequestManager的流程。

Glide.with(Context).load(url)

上面分析了Glide.with是创建RequestManager的过程,那其实load方法也就对应了RequestManager的load方法:

1
2
3
public RequestBuilder<Drawable> load(@Nullable String string) {
  return asDrawable().load(string);
}

我们通过传进来的string作为讲解,首先调用了asDrawable方法:

1
2
3
4
5
6
7
8
public RequestBuilder<Drawable> asDrawable() {
  return as(Drawable.class);
}

public <ResourceType> RequestBuilder<ResourceType> as(
    @NonNull Class<ResourceType> resourceClass) {
  return new RequestBuilder<>(glide, this, resourceClass, context);
}

将Drawable作为RequestBuilder的泛型,并返回了RequestBuilder实例,接着看RequestBuilder的load方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
  if (isAutoCloneEnabled()) {
    return clone().loadGeneric(model);
  }
  this.model = model;
  isModelSet = true;
  return selfOrThrowIfLocked();
}

load方法将url传给了RequestBuilder的model属性,然后返回自己。

Glide.with(Context).load(url).into(imageView)

调完load方法,实际就返回了RequestBuilder对象了。所以into就是它的方法了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
  Util.assertMainThread();
  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:
    }
  }
  return into(
      glideContext.buildImageViewTarget(view, transcodeClass),
      /* targetListener= */ null,
      requestOptions,
      Executors.mainThreadExecutor());
}

RequestBbuilder继承自BaseRequestOptions,在into里面首先通过imageView的scaleType,然后生成不同的BaseRequestOptions,然后通过glideContext.buildImageViewTarget方法将ImageView包装成ViewTarget:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
    @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
  return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}

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

上面分析过clazz传进来的是Drawable.class,所以会包装成DrawableImageViewTarget。 接着调用了另外一个into方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
private <Y extends Target<TranscodeType>> Y into(
    @NonNull Y target,
    @Nullable RequestListener<TranscodeType> targetListener,
    BaseRequestOptions<?> options,
    Executor callbackExecutor) {
  Request request = buildRequest(target, targetListener, options, callbackExecutor);

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

  requestManager.clear(target);
  target.setRequest(request);
  requestManager.track(target, request);

  return target;
}

首先调用了buildRequest方法来构建Request,然后获取target的request和当前request是不是同一个,如果是的话,则直接返回已经存在的target,否则调用requestManager.track,我们先看buildRequest:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private Request buildRequest(
    Target<TranscodeType> target,
    @Nullable RequestListener<TranscodeType> targetListener,
    BaseRequestOptions<?> requestOptions,
    Executor callbackExecutor) {
  return buildRequestRecursive(
      /* requestLock= */ new Object(),
      target,
      targetListener,
      /* parentCoordinator= */ null,
      transitionOptions,
      requestOptions.getPriority(),
      requestOptions.getOverrideWidth(),
      requestOptions.getOverrideHeight(),
      requestOptions,
      callbackExecutor);
}

private Request buildRequestRecursive(
    Object requestLock,
    Target<TranscodeType> target,
    @Nullable RequestListener<TranscodeType> targetListener,
    @Nullable RequestCoordinator parentCoordinator,
    TransitionOptions<?, ? super TranscodeType> transitionOptions,
    Priority priority,
    int overrideWidth,
    int overrideHeight,
    BaseRequestOptions<?> requestOptions,
    Executor callbackExecutor) {
  Request mainRequest =
      buildThumbnailRequestRecursive(
          requestLock,
          target,
          targetListener,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          requestOptions,
          callbackExecutor);

  return mainRequest;
}

上面的buildRequestRecursive方法省去了errorBuilder相关的处理,默认是不用去处理的,所以可以看到上面构建Request实际调用了buildThumbnailRequestRecursive方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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) {
  return obtainRequest(
      requestLock,
      target,
      targetListener,
      requestOptions,
      parentCoordinator,
      transitionOptions,
      priority,
      overrideWidth,
      overrideHeight,
      callbackExecutor);
}

上面也是省去了其他相关逻辑,所以我们直接看obtainRequest方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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);
}

public static <R> SingleRequest<R> obtain(
    Context context,
    GlideContext glideContext,
    Object requestLock,
    Object model,
    Class<R> transcodeClass,
    BaseRequestOptions<?> requestOptions,
    int overrideWidth,
    int overrideHeight,
    Priority priority,
    Target<R> target,
    RequestListener<R> targetListener,
    @Nullable List<RequestListener<R>> requestListeners,
    RequestCoordinator requestCoordinator,
    Engine engine,
    TransitionFactory<? super R> animationFactory,
    Executor callbackExecutor) {
  return new SingleRequest<>(
      context,
      glideContext,
      requestLock,
      model,
      transcodeClass,
      requestOptions,
      overrideWidth,
      overrideHeight,
      priority,
      target,
      targetListener,
      requestListeners,
      requestCoordinator,
      engine,
      animationFactory,
      callbackExecutor);
}

上面都没什么好说的,直接new了一个SingleRequest,此处SingleRequest的发型是Drawable,这是在上面分析load的时候知道的,先明确这点。我们再回到上面RequestBuilder的into方法,先构建一个SingleRequest,然后看当前target的request和构建的SingleRequest是不是同一个,如果是直接返回,如果不是调用requestManager.track,先看target.getRequest,前面分析过target是一个DrawableImageViewTarget,它的父父类ViewTarget:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public Request getRequest() {
  Object tag = getTag();
  Request request = null;
  if (tag != null) {
    if (tag instanceof Request) {
      request = (Request) tag;
    } else {
      throw new IllegalArgumentException(
          "You must not call setTag() on a view Glide is targeting");
    }
  }
  return request;
}

private static int tagId = R.id.glide_custom_view_target_tag;
private Object getTag() {
  return view.getTag(tagId);
}

public void setRequest(@Nullable Request request) {
  setTag(request);
}

private void setTag(@Nullable Object tag) {
  isTagUsedAtLeastOnce = true;
  view.setTag(tagId, tag);
}

可以看到request是塞入到view的tag上,并且该tag是绑定了一个id。接着看下requestManager.track:

1
2
3
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
  targetTracker.track(target);
  requestTracker.runRequest(request);

将target放到TargetTracker中:

1
2
3
4
5
private final Set<Target<?>> targets =
    Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());
public void track(@NonNull Target<?> target) {
  targets.add(target);
}

将target只是放到set集合中,后面会用到,先不用管。重要看RequestTracker的runRequest方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private final Set<Request> requests =
    Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
public void runRequest(@NonNull Request request) {
  requests.add(request);
  if (!isPaused) {
    request.begin();
  } else {
    request.clear();
    pendingRequests.add(request);
  }
}

首先将request也是放到set集合中,接着判断当前是不是pause状态,默认不是pause状态,则调用request的begin方法,前面分析过该request实际是SingleRequest:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public void begin() {
  synchronized (requestLock) {

    experimentalNotifyRequestStarted(model);

    status = Status.WAITING_FOR_SIZE;//默认状态
    //如果重写了override方法来制定加载图片的大小
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } else {
      //如果没有制定大小走此处
      target.getSize(this);
    }

    if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
        && canNotifyStatusChanged()) {
          //回调start的状态
      target.onLoadStarted(getPlaceholderDrawable());
    }
  }
}

如果没有通过override方法制定加载图片的大小,则调用target.getSize方法:

1
2
3
public void getSize(@NonNull SizeReadyCallback cb) {
  sizeDeterminer.getSize(cb);
}

调用了内部类SizeDeterminer的getSize方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
void getSize(@NonNull SizeReadyCallback cb) {
  //获取target的宽高
  int currentWidth = getTargetWidth();
  int currentHeight = getTargetHeight();
  //如果宽高校验通过则回调到SingleRequest的onSizeReady
  if (isViewStateAndSizeValid(currentWidth, currentHeight)) {
    cb.onSizeReady(currentWidth, currentHeight);
    return;
  }
  if (!cbs.contains(cb)) {
    cbs.add(cb);
  }
  if (layoutListener == null) {
    ViewTreeObserver observer = view.getViewTreeObserver();
    layoutListener = new SizeDeterminerLayoutListener(this);
    //否则监听绘制的前置事件
    observer.addOnPreDrawListener(layoutListener);
  }
}

获取target的宽高,如果宽高校验通过则回调到SingleRequest中,否则监听target的绘制前置事件。我们看下如何获取宽高的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private int getTargetWidth() {
  int horizontalPadding = view.getPaddingLeft() + view.getPaddingRight();
  LayoutParams layoutParams = view.getLayoutParams();
  int layoutParamSize = layoutParams != null ? layoutParams.width : PENDING_SIZE;
  return getTargetDimen(view.getWidth(), layoutParamSize, horizontalPadding);
}

private int getTargetDimen(int viewSize, int paramSize, int paddingSize) {
  int adjustedParamSize = paramSize - paddingSize;
  //如果layoutParams中设置了精确宽度
  if (adjustedParamSize > 0) {
    return adjustedParamSize;
  }

  //默认不走这里
  if (waitForLayout && view.isLayoutRequested()) {
    return PENDING_SIZE;
  }

  //默认viewSize等于0,也不走这里
  int adjustedViewSize = viewSize - paddingSize;
  if (adjustedViewSize > 0) {
    return adjustedViewSize;
  }
  //如果imageView没有经过测量,并且宽度设置的是WRAP_CONTENT,走这里
  if (!view.isLayoutRequested() && paramSize == LayoutParams.WRAP_CONTENT) {
    return getMaxDisplayLength(view.getContext());
  }
  return PENDING_SIZE;
}

我们只分析宽度和高度为LayoutParams.WRAP_CONTENT情况,此时会调getMaxDisplayLength:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private static int getMaxDisplayLength(@NonNull Context context) {
  if (maxDisplayLength == null) {
    WindowManager windowManager =
        (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = Preconditions.checkNotNull(windowManager).getDefaultDisplay();
    Point displayDimensions = new Point();
    display.getSize(displayDimensions);
    maxDisplayLength = Math.max(displayDimensions.x, displayDimensions.y);
  }
  return maxDisplayLength;
}

可以看到获取的是屏幕的宽高,所以如果没有imageView定宽高,并且还没到测量的时候,此时设置的初始宽高是屏幕的宽高。获取到默认宽高后会回调到SingleRequest的onSizeReady:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public void onSizeReady(int width, int height) {
  synchronized (requestLock) {
    if (status != Status.WAITING_FOR_SIZE) {
      return;
    }
    status = Status.RUNNING;
    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;
    }
  }
}

调用了Engine的load方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public <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) {
  //构建EngineKey,由于不需要外部去控制key,所以keyFactory是一个普通的factory,不需要进行扩展
  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);
    }
  }

  cb.onResourceReady(
      memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
  return null;
}

先不用管内存加载这块,直接看waitForExistingOrStartNewJob方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
private <R> LoadStatus waitForExistingOrStartNewJob(
    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,
    EngineKey key,
    long startTime) {
  //从已存在的job列表中找相同的EngineJob
  EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
  if (current != null) {
    current.addCallback(cb, callbackExecutor);
    return new LoadStatus(cb, current);
  }
  //如果没有找到相同的EngineJob,则构建一个新的出来
  EngineJob<R> engineJob =
      engineJobFactory.build(
          key,
          isMemoryCacheable,
          useUnlimitedSourceExecutorPool,
          useAnimationPool,
          onlyRetrieveFromCache);
  //构建DecodeJob
  DecodeJob<R> decodeJob =
      decodeJobFactory.build(
          glideContext,
          model,
          key,
          signature,
          width,
          height,
          resourceClass,
          transcodeClass,
          priority,
          diskCacheStrategy,
          transformations,
          isTransformationRequired,
          isScaleOnlyOrNoTransform,
          onlyRetrieveFromCache,
          options,
          engineJob);
  //将构建好的EngineJob放到job列表中
  jobs.put(key, engineJob);
  //将cb添加到EngineJob中作为回调,这里的cb是前面的SingleRequest
  engineJob.addCallback(cb, callbackExecutor);
  //触发加载逻辑
  engineJob.start(decodeJob);
  return new LoadStatus(cb, engineJob);
}

上面创建EngineJob和DecodeJob,从名字看EngineJob是专门用来加载主逻辑的Job,DecodeJob是解码用的。先不管它们是怎么创建的,后面会讲到,直接看EngineJob的start方法:

1
2
3
4
5
6
public synchronized void start(DecodeJob<R> decodeJob) {
  this.decodeJob = decodeJob;
  GlideExecutor executor =
      decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
  executor.execute(decodeJob);
}

此时将DecodeJob作为runnable放到线程池中执行,看下它的run方法:

1
2
3
public void run() {
  runWrapped();
}

其余的代码删除掉了,只保留核心的方法调用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
private void runWrapped() {
  switch (runReason) {
    case INITIALIZE:
      stage = getNextStage(Stage.INITIALIZE);
      currentGenerator = getNextGenerator();
      runGenerators();
      break;
    case SWITCH_TO_SOURCE_SERVICE:
      runGenerators();
      break;
    case DECODE_DATA:
      decodeFromRetrievedData();
      break;
  }
}

runReason的默认值是INITIALIZE,然后调用getNextStage获取到当前stage,然后通过getNextGenerator获取下一个generator,然后调用runGenerators来执行generator,来看下这一段逻辑:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
private Stage getNextStage(Stage current) {
  switch (current) {
    case INITIALIZE:
      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:
      return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
    case SOURCE:
    case FINISHED:
      return Stage.FINISHED;
    default:
      throw new IllegalArgumentException("Unrecognized stage: " + current);
  }
}

默认是支持decodeCachedResource的,它表示是否获取解码后的缓存资源,所以此时返回Stage.RESOURCE_CACHE,接着调用getNextGenerator方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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);
  }
}

创建了ResourceCacheGenerator,然后调用runGenerators方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
private void runGenerators() {
  boolean isStarted = false;
  //调用当前的generator,如果它的startNext方法返回false,则继续获取下一个stage,并继续调用下一个generator的startNext方法
  while (!isCancelled
      && currentGenerator != null
      && !(isStarted = currentGenerator.startNext())) {
    stage = getNextStage(stage);
    currentGenerator = getNextGenerator();
    if (stage == Stage.SOURCE) {
      reschedule(RunReason.SWITCH_TO_SOURCE_SERVICE);
      return;
    }
  }
  if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
    notifyFailed();
  }
}

我们直接看stage为SOURCE,generator直接是SourceGenerator时候,看下它的startNext方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public boolean startNext() {
  //如果已经缓存上了,直接用缓存的数据
  if (dataToCache != null) {
    Object data = dataToCache;
    dataToCache = null;
    try {
      boolean isDataInCache = cacheData(data);
      if (!isDataInCache) {
        return true;
      }
    } catch (IOException e) {
    }
  }
  //如果sourceCacheGenerator中能拿到数据直接返回
  if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
    return true;
  }
  sourceCacheGenerator = null;

  loadData = null;
  boolean started = false;
  //从DecodeHelper中获取loadData
  while (!started && hasNextModelLoader()) {
    loadData = helper.getLoadData().get(loadDataListIndex++);
    if (loadData != null
        && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
            || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
      started = true;
      //如果存在loadData则调该方法
      startNextLoad(loadData);
    }
  }
  return started;
}

startNext中首先从DecodeHelper中获取到loadData,此处我们先不用管怎么获取到loadData,获取到loadData后调用startNextLoad方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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);
          }
        }
      });
}

此时调用loadData中的fetcher的loadData方法,此处的loadData.fetcher是谁呢?这个后面的章节再了解,先知道是HttpUrlFetcher,然后看下它的loadData方法:

1
2
3
4
5
6
7
8
9
public void loadData(
    @NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
  try {
    InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
    callback.onDataReady(result);
  } catch (IOException e) {
    callback.onLoadFailed(e);
  } 
}

调用了loadDataWithRedirects方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
private InputStream loadDataWithRedirects(
      URL url, int redirects, URL lastUrl, Map<String, String> headers) throws HttpException {

    urlConnection = buildAndConfigureConnection(url, headers);

    try {
      urlConnection.connect();
      stream = urlConnection.getInputStream();
    } catch (IOException e) {
      throw new HttpException(
          "Failed to connect or obtain data", getHttpStatusCodeOrInvalid(urlConnection), e);
    }

    if (isCancelled) {
      return null;
    }

    final int statusCode = getHttpStatusCodeOrInvalid(urlConnection);
    if (isHttpOk(statusCode)) {
      return getStreamForSuccessfulRequest(urlConnection);
    }
  }

通过buildAndConfigureConnection创建了HttpURLConnection,接着通过code码解析对应的InputStream,结束后回调到SourceGenerator内部类DataCallback的onDataReady,然后回调到SourceGenerator的onDataReadyInternal:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
void onDataReadyInternal(LoadData<?> loadData, Object data) {
  DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
  
  if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
    dataToCache = data;
    cb.reschedule();
  } else {
    cb.onDataFetcherReady(
        loadData.sourceKey,
        data,
        loadData.fetcher,
        loadData.fetcher.getDataSource(),
        originalKey);
  }
}

将获取到的数据给到dataToCache,并且回调到DecodeJob的reschedule方法:

1
2
3
4
5
6
7
8
public void reschedule() {
  reschedule(RunReason.SWITCH_TO_SOURCE_SERVICE);
}

private void reschedule(RunReason runReason) {
  this.runReason = runReason;
  callback.reschedule(this);
}

此处的callback是EngineJob,继续回调到reschedule:

1
2
3
public void reschedule(DecodeJob<?> job) {
  getActiveSourceExecutor().execute(job);
}

此处又是一个线程池,再次执行DecodeJob,注意了此时DecodeJob中的runReason是SWITCH_TO_SOURCE_SERVICE,又回到刚才说的runWrapped方法中:

1
2
3
4
5
6
7
private void runWrapped() {
  switch (runReason) {
    case SWITCH_TO_SOURCE_SERVICE:
      runGenerators();
      break;
  }
}
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy