This is the 10th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Glide call process

val requestManager = Glide.with(this);

val requestBuilder = requestManager.load("");

val target = requestBuilder.into(imageView)

Copy the code
  1. Call Glide. With (this) to create a RequestManager object.
  2. Load an image URL to return the RequestBuilder object (whose stereotype type is Drawable).
  3. The requestBuilder calls into to make the injected ImageView display the image of the corresponding URL

The RequestManager creation process

The process of building a RequestManager is returned by Glide calling the with method (with the Activity as an argument).

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

Enter the getRetriever method

@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  Preconditions.checkNotNull(
      context,
      "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
          + "returns null (which usually occurs when getActivity() is called before the Fragment "
          + "is attached or after the Fragment is destroyed).");
  return Glide.get(context).getRequestManagerRetriever();
}
Copy the code

Return a RequestManagerRetriever object, so the RequestManager object is built from the RequestManagerRetriever. Let’s first look at glide’s get method:

public static Glide get(@NonNull Context context) {
  if (glide == null) {
    GeneratedAppGlideModule annotationGeneratedModule =
        getAnnotationGeneratedGlideModules(context.getApplicationContext());
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context, annotationGeneratedModule);
      }
    }
  }

  return glide;
}
Copy the code

The checkAndInitializeGlide method calls initializeGlide() internally to initializeGlide.

private static void initializeGlide( @NonNull Context context, @NonNull GlideBuilder builder, @Nullable GeneratedAppGlideModule annotationGeneratedModule) { ... / / initializes the Glide RequestManagerRetriever object held RequestManagerRetriever. RequestManagerFactory factory = annotationGeneratedModule ! = null ? annotationGeneratedModule.getRequestManagerFactory() : null; builder.setRequestManagerFactory(factory); for (com.bumptech.glide.module.GlideModule module : manifestModules) { module.applyOptions(applicationContext, builder); } if (annotationGeneratedModule ! = null) { annotationGeneratedModule.applyOptions(applicationContext, builder); } Glide glide = builder.build(applicationContext); for (com.bumptech.glide.module.GlideModule module : manifestModules) { try { module.registerComponents(applicationContext, glide, glide.registry); } catch (AbstractMethodError e) { } } if (annotationGeneratedModule ! = null) { annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry); } applicationContext.registerComponentCallbacks(glide); // Create glide. Glide = glide; }Copy the code

Glide’s RequestManagerRetriever initialization is also very simple, but one more thing to note is that this object requires a requestManagerFactory object. Glide default objects are used if the requestManagerFactory object client is not set.

public RequestManagerRetriever( @Nullable RequestManagerFactory factory, GlideExperiments experiments) { this.factory = factory ! = null ? factory : DEFAULT_FACTORY; handler = new Handler(Looper.getMainLooper(), this /* Callback */); frameWaiter = buildFrameWaiter(experiments); }Copy the code

The default RequestManagerFactory 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) { return new RequestManager(glide, lifecycle, requestManagerTreeNode, context); }};Copy the code

So far the RequestManagerRetriever object has been built, and the RequestManger object is obtained from the RequestManagerRetriever get method mentioned above, so let’s take a look at what the get method does:

public RequestManager get(@NonNull Activity activity) { if (Util.isOnBackgroundThread()) { return get(activity.getApplicationContext()); } else if (activity instanceof FragmentActivity) { return get((FragmentActivity) activity); } else { assertNotDestroyed(activity); frameWaiter.registerSelf(activity); android.app.FragmentManager fm = activity.getFragmentManager(); return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity)); }}Copy the code

Enter the fragmentGet method to see the RequestManager creation process

private RequestManager fragmentGet( @NonNull Context context, @NonNull android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint, boolean isParentVisible) { RequestManagerFragment current = getRequestManagerFragment(fm, parentHint); RequestManager requestManager = current.getRequestManager(); If (requestManager == null) {// Initialize requestManager Glide Glide = Glide. Get (context); requestManager = factory.build( glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context); if (isParentVisible) { requestManager.onStart(); } current.setRequestManager(requestManager); } return requestManager; }Copy the code

That is, the RequestManager is created by calling the factory class DEFAULT_FACTORY above when it is first initialized. If used again, it is retrieved from the RequestManagerFragment object.

RequestManager (RequestManager) {RequestManager (RequestManager) {RequestManager (RequestManager);

  1. Glide initializes by creating a RequestManagerRetriever object that holds the RequestManagerFactory factory interface that builds the RequestManager object. The interface client can use its own implementation to build RequestManager objects, or it can implement the DEFAULT_FACTORY class using Glide’s default factory interface.
  2. Initialize the RequestManager using the Get method in the RequestManagerRetriever or call the Factory build method to complete the build of the RequestManager.

The process of creating a RequestBuilder

Public RequestBuilder<Drawable> Load (@nullable String String String) {return asDrawable().load(string); } //asDrawable public RequestBuilder<Drawable> asDrawable() { return as(Drawable.class); } public <ResourceType> RequestBuilder<ResourceType> as( @NonNull Class<ResourceType> resourceClass) { return new RequestBuilder<>(glide, this, resourceClass, context); }Copy the code

Load eventually calls the asDrawable method and then the AS method to set the RequestBuidler template to Drawable and new a RequestBuilder object.

protected RequestBuilder( @NonNull Glide glide, RequestManager requestManager, Class<TranscodeType> transcodeClass, Context context) { this.glide = glide; this.requestManager = requestManager; Drawable. Class this. TranscodeClass = transcodeClass; this.context = context; / / get the default TransitionOptions object enclosing TransitionOptions = requestManager. GetDefaultTransitionOptions (transcodeClass); this.glideContext = glide.getGlideContext(); initRequestListeners(requestManager.getDefaultRequestListeners()); apply(requestManager.getDefaultRequestOptions()); }Copy the code

After the asDrawable method is called, the Load (Model) method is called.

public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}
//loadGeneric
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
  if (isAutoCloneEnabled()) {
    return clone().loadGeneric(model);
  }
  this.model = model;
  isModelSet = true;
  return selfOrThrowIfLocked();
}

Copy the code

The load method in turn calls the loadGeneric method, which sets the Model property (again, the URL of the image) and the isModelSet variable.

At this point the RequestBuilder object is built

A brief description of ViewTarget

public ViewTarget<ImageView, TranscodeType > into (@ NonNull ImageView view) {/ / omitted to set parameters of processing code return into (glideContext. BuildImageViewTarget (view, transcodeClass), /*targetListener=*/ null, requestOptions, Executors.mainThreadExecutor()); }Copy the code

The into method ends up calling another into overloaded method, which calls the buildImageViewTarget method of the GlideContext object before calling the overloaded method. When Glide is created by calling the GlideBuilder, Initialize the GlideContext object inside the Glide constructor.

ImageViewTargetFactory = new ImageViewTargetFactory(); GlideContext = new GlideContext(context, arrayPool, Registry, imageViewTargetFactory, defaultRequestOptionsFactory, defaultTransitionOptions, defaultRequestListeners, engine, experiments, logLevel);Copy the code

The GlideContext buildImageViewTarget

@NonNull
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
    @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
  return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
Copy the code

ImageViewTargetFactory is called to create a Target

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 {
   
  }
}
Copy the code

Since we passed a Drawable, the factory class returns a DrawableImageViewTarget object that holds a reference to the target ImageView. The buildImageViewTarget call is followed by passing the generated target object to the into overload method

public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
  return into(target, /*targetListener=*/ null, Executors.mainThreadExecutor());
}
Copy the code

The into overloaded method then calls another overloaded method:

private <Y extends Target<TranscodeType>> Y into( @NonNull Y target, @Nullable RequestListener<TranscodeType> targetListener, BaseRequestOptions<? > options, Executor callbackExecutor) { Preconditions.checkNotNull(target); if (! isModelSet) { throw new IllegalArgumentException("You must call #load() before calling #into()"); } 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; }Copy the code

The into method is called, and the result of this execution is that it returns an implementation class for the Target interface. Glide itself provides a variety of Target implementation classes.

Creation of the Request object

RequestBuilder (Ruquest); Request (Ruquest); Request (Ruquest); Request (Ruquest)

Request request = buildRequest(target, targetListener, options, callbackExecutor);
Copy the code

Glide Request is an interface.

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); }Copy the code

Enter the buildRequestRecursive method

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) { ErrorRequestCoordinator errorRequestCoordinator = 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; } int errorOverrideWidth = errorBuilder.getOverrideWidth(); int errorOverrideHeight = errorBuilder.getOverrideHeight(); if (Util.isValidDimensions(overrideWidth, overrideHeight) && ! errorBuilder.isValidOverride()) { errorOverrideWidth = requestOptions.getOverrideWidth(); errorOverrideHeight = requestOptions.getOverrideHeight(); } Request errorRequest = errorBuilder.buildRequestRecursive( requestLock, target, targetListener, errorRequestCoordinator, errorBuilder.transitionOptions, errorBuilder.getPriority(), errorOverrideWidth, errorOverrideHeight, errorBuilder, callbackExecutor); errorRequestCoordinator.setRequests(mainRequest, errorRequest); return errorRequestCoordinator; }Copy the code

Enter the buildThumbnailRequestRecursive method

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) { if (isThumbnailBuilt) { throw new IllegalStateException( "You cannot use a request as both the main request and a " + "thumbnail, consider using clone() on the request(s) passed to thumbnail()"); } TransitionOptions<? ,? super TranscodeType> thumbTransitionOptions = thumbnailBuilder.transitionOptions; if (thumbnailBuilder.isDefaultTransitionOptionsSet) { thumbTransitionOptions = transitionOptions; } Priority thumbPriority = thumbnailBuilder.isPrioritySet() ? thumbnailBuilder.getPriority() : getThumbnailPriority(priority); int thumbOverrideWidth = thumbnailBuilder.getOverrideWidth(); int thumbOverrideHeight = thumbnailBuilder.getOverrideHeight(); if (Util.isValidDimensions(overrideWidth, overrideHeight) && ! thumbnailBuilder.isValidOverride()) { thumbOverrideWidth = requestOptions.getOverrideWidth(); thumbOverrideHeight = requestOptions.getOverrideHeight(); } ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(requestLock, parentCoordinator); Request fullRequest = obtainRequest( requestLock, target, targetListener, requestOptions, coordinator, transitionOptions, priority, overrideWidth, overrideHeight, callbackExecutor); isThumbnailBuilt = true; Request thumbRequest = thumbnailBuilder.buildRequestRecursive( requestLock, target, targetListener, coordinator, thumbTransitionOptions, thumbPriority, thumbOverrideWidth, thumbOverrideHeight, thumbnailBuilder, callbackExecutor); isThumbnailBuilt = false; coordinator.setRequests(fullRequest, thumbRequest); return coordinator; } else if (thumbSizeMultiplier ! = null) { ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(requestLock, parentCoordinator); Request fullRequest = obtainRequest( requestLock, target, targetListener, requestOptions, coordinator, transitionOptions, priority, overrideWidth, overrideHeight, callbackExecutor); BaseRequestOptions<? > thumbnailOptions = requestOptions.clone().sizeMultiplier(thumbSizeMultiplier); Request thumbnailRequest = obtainRequest( requestLock, target, targetListener, thumbnailOptions, coordinator, transitionOptions, getThumbnailPriority(priority), overrideWidth, overrideHeight, callbackExecutor); coordinator.setRequests(fullRequest, thumbnailRequest); return coordinator; } else { return obtainRequest( requestLock, target, targetListener, requestOptions, parentCoordinator, transitionOptions, priority, overrideWidth, overrideHeight, callbackExecutor); }}Copy the code

Enter the obtainRequest method and return a SingleRequest object.

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); }Copy the code

Glide’s rough work flow

  1. Glide object is built by GlideBuilder
  2. Create the RequestManagerRetriever object when you build the Glide object
  3. The RequestManager object is built from the factory class requestManagerFactory held by the RequestManangerRetriever object.
  4. The RequestManager calls the Load method to build a RequestBuilder object
  5. RequestBuilder calls buildRequest to build a Request object when called into, and into returns a specific Target object via the ImageViewTargetFactory factory class.