主流框架开源库

主流开源库-Glide源码分析

2020-04-15  本文已影响0人  isLJli

总结:
Glide.with(this)主要是生成一个不可以的Fragment绑定actvity中,所以在actvity的生命周期变化的时候会传到fragement以此达到监控生命周期的目的。同时fragment会把我们的requestManager存起来。

RequestManager.load("{}"):主要是通过我们的requestBuilder把我们的传进去资源路径存好

RequestBuilder.into():1.先根据类型生成一个target,通过target生成一个request请求,2.确定好view的大小后,调用Engine.load()先查看是否有缓存,然后在异步执行一系列的操作通过网络请求拿到inputStream,再把inputStream转换成Bitmap,再把Bitmap转成Resource。
3.拿到Resource之后先判断gif还是静态图,然后对其进行转码生成Drawable,通过handler切换到主线程,通过target进行图片的加载。

这里追踪一下,如何通过fragment的Lifecycle给requesrtManager达到控制生命周期:

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
  RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
      RequestManagerFragment current = getRequestManagerFragment(fm);
      RequestManager requestManager = current.getRequestManager();
      if (requestManager == null) { //这里把fragment的Lifecycle传进去requestManager里
          requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
          current.setRequestManager(requestManager);
      }
      return requestManager;
  }


public class RequestManager implements LifecycleListener {
private final Lifecycle lifecycle;
RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
          RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
      this.context = context.getApplicationContext();
      this.lifecycle = lifecycle;
      //为lifecycle添加监听事件
      if (Util.isOnBackgroundThread()) {
          new Handler(Looper.getMainLooper()).post(new Runnable() {
              @Override
              public void run() {
                  lifecycle.addListener(RequestManager.this);
              }
          });
      } else {
          lifecycle.addListener(this);
      }
      lifecycle.addListener(connectivityMonitor);
  }

//RequestManager 实现了LifecycleListener接口
public void onStart() {
      // onStart might not be called because this object may be created after the fragment/activity's onStart method.
      resumeRequests();
  }
@Override
  public void onStop() {
      pauseRequests();
  }
public void onDestroy() {
      requestTracker.clearRequests();
  }
}

public interface LifecycleListener {

  void onStart();

  void onStop();

  void onDestroy();
}


frement{
private final ActivityFragmentLifecycle lifecycle;

@Override
  public void onStart() {
      super.onStart();
      lifecycle.onStart();
  }

  @Override
  public void onStop() {
      super.onStop();
      lifecycle.onStop();
  }

  @Override
  public void onDestroy() {
      super.onDestroy();
      lifecycle.onDestroy();
  }
}

class ActivityFragmentLifecycle implements Lifecycle {
  private final Set<LifecycleListener> lifecycleListeners =
          Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
  private boolean isStarted;
  private boolean isDestroyed;
  @Override
  public void addListener(LifecycleListener listener) {
      lifecycleListeners.add(listener);

      if (isDestroyed) {
          listener.onDestroy();
      } else if (isStarted) {
          listener.onStart();
      } else {
          listener.onStop();
      }
  }

  void onStart() {
      isStarted = true;
      for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
          lifecycleListener.onStart();
      }
  }

  void onStop() {
      isStarted = false;
      for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
          lifecycleListener.onStop();
      }
  }

  void onDestroy() {
      isDestroyed = true;
      for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
          lifecycleListener.onDestroy();
      }
  }
}

public interface Lifecycle {

  void addListener(LifecycleListener listener);
}

总结:fragment有一个lifecycler接口的实例,实例通过拿到一个lifecyclerListener来实行具体操作,fragment在生命周期onstart等调用lifecycler实例的方法,告诉lifecycler现在的生命周期状况并进行操作。requestManager实现了lifecyclerListener接口,做一些具体的操作。

load()路线分析:

public class RequestManager implements LifecycleListener {

  ...

  public DrawableTypeRequest<String> load(String string) {
      return (DrawableTypeRequest<String>) fromString().load(string);
  }

  public DrawableTypeRequest<String> fromString() {
      return loadGeneric(String.class);
  }

//主要生成两个ModelLoader实例给DrawableTypeRequest对象
  private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
//这个类主要是看看是否需要强制转换成bitmap、gif。默认是Drawable
      ModelLoader<T, InputStream> streamModelLoader = 
           Glide.buildStreamModelLoader(modelClass, context);
      ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
           Glide.buildFileDescriptorModelLoader(modelClass, context);
      if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
          throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
                  + " which there is a registered ModelLoader, if you are using a custom model, you must first call"
                  + " Glide#register with a ModelLoaderFactory for your custom model class");
      }
      return optionsApplier.apply(
              new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                      glide, requestTracker, lifecycle, optionsApplier));
  }
  ...
}

//看看DrawableTypeRequest干什么
public class DrawableTypeRequest<ModelType> extends DrawableRequestBuilder<ModelType> implements DownloadOptions {
//
  private final ModelLoader<ModelType, InputStream> streamModelLoader;
  private final ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader;
  private final RequestManager.OptionsApplier optionsApplier;

 //asBitmap强制返回BitmapTypeRequest
  public BitmapTypeRequest<ModelType> asBitmap() {
      return optionsApplier.apply(new BitmapTypeRequest<ModelType>(this, streamModelLoader,
              fileDescriptorModelLoader, optionsApplier));
  }
  
  //asGif强制返回GifTypeRequest
  public GifTypeRequest<ModelType> asGif() {
      return optionsApplier.apply(new GifTypeRequest<ModelType>(this, streamModelLoader, optionsApplier));
  }
//怎么没有看见load()方法?在它的父类中
 ...
}
//DrawableTypeRequest的父类就是DrawableRequestBuilder

public class DrawableRequestBuilder<ModelType>
      extends GenericRequestBuilder<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable>
      implements BitmapOptions, DrawableOptions {
 //这个类中方法就是Glide的大多数API,具体的操作都给类父类GenericRequestBuilder执行,并返回了自己的对象
  DrawableRequestBuilder(Context context, Class<ModelType> modelClass,
          LoadProvider<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable> loadProvider, Glide glide,
          RequestTracker requestTracker, Lifecycle lifecycle) {
      super(context, modelClass, loadProvider, GlideDrawable.class, glide, requestTracker, lifecycle);
      // Default to animating.
      crossFade();
  }

  public DrawableRequestBuilder<ModelType> thumbnail(
          DrawableRequestBuilder<?> thumbnailRequest) {
      super.thumbnail(thumbnailRequest);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> thumbnail(
          GenericRequestBuilder<?, ?, ?, GlideDrawable> thumbnailRequest) {
      super.thumbnail(thumbnailRequest);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> thumbnail(float sizeMultiplier) {
      super.thumbnail(sizeMultiplier);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> sizeMultiplier(float sizeMultiplier) {
      super.sizeMultiplier(sizeMultiplier);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> decoder(ResourceDecoder<ImageVideoWrapper, GifBitmapWrapper> decoder) {
      super.decoder(decoder);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> cacheDecoder(ResourceDecoder<File, GifBitmapWrapper> cacheDecoder) {
      super.cacheDecoder(cacheDecoder);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> encoder(ResourceEncoder<GifBitmapWrapper> encoder) {
      super.encoder(encoder);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> priority(Priority priority) {
      super.priority(priority);
      return this;
  }

  public DrawableRequestBuilder<ModelType> transform(BitmapTransformation... transformations) {
      return bitmapTransform(transformations);
  }

  public DrawableRequestBuilder<ModelType> centerCrop() {
      return transform(glide.getDrawableCenterCrop());
  }

  public DrawableRequestBuilder<ModelType> fitCenter() {
      return transform(glide.getDrawableFitCenter());
  }

  public DrawableRequestBuilder<ModelType> bitmapTransform(Transformation<Bitmap>... bitmapTransformations) {
      GifBitmapWrapperTransformation[] transformations =
              new GifBitmapWrapperTransformation[bitmapTransformations.length];
      for (int i = 0; i < bitmapTransformations.length; i++) {
          transformations[i] = new GifBitmapWrapperTransformation(glide.getBitmapPool(), bitmapTransformations[i]);
      }
      return transform(transformations);
  }

  @Override
  public DrawableRequestBuilder<ModelType> transform(Transformation<GifBitmapWrapper>... transformation) {
      super.transform(transformation);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> transcoder(
          ResourceTranscoder<GifBitmapWrapper, GlideDrawable> transcoder) {
      super.transcoder(transcoder);
      return this;
  }

  public final DrawableRequestBuilder<ModelType> crossFade() {
      super.animate(new DrawableCrossFadeFactory<GlideDrawable>());
      return this;
  }

  public DrawableRequestBuilder<ModelType> crossFade(int duration) {
      super.animate(new DrawableCrossFadeFactory<GlideDrawable>(duration));
      return this;
  }

  public DrawableRequestBuilder<ModelType> crossFade(int animationId, int duration) {
      super.animate(new DrawableCrossFadeFactory<GlideDrawable>(context, animationId,
              duration));
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> dontAnimate() {
      super.dontAnimate();
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> animate(ViewPropertyAnimation.Animator animator) {
      super.animate(animator);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> animate(int animationId) {
      super.animate(animationId);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> placeholder(int resourceId) {
      super.placeholder(resourceId);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> placeholder(Drawable drawable) {
      super.placeholder(drawable);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> fallback(Drawable drawable) {
      super.fallback(drawable);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> fallback(int resourceId) {
      super.fallback(resourceId);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> error(int resourceId) {
      super.error(resourceId);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> error(Drawable drawable) {
      super.error(drawable);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> listener(
          RequestListener<? super ModelType, GlideDrawable> requestListener) {
      super.listener(requestListener);
      return this;
  }
  @Override
  public DrawableRequestBuilder<ModelType> diskCacheStrategy(DiskCacheStrategy strategy) {
      super.diskCacheStrategy(strategy);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> skipMemoryCache(boolean skip) {
      super.skipMemoryCache(skip);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> override(int width, int height) {
      super.override(width, height);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> sourceEncoder(Encoder<ImageVideoWrapper> sourceEncoder) {
      super.sourceEncoder(sourceEncoder);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> dontTransform() {
      super.dontTransform();
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> signature(Key signature) {
      super.signature(signature);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> load(ModelType model) {
      super.load(model);
      return this;
  }

  @Override
  public DrawableRequestBuilder<ModelType> clone() {
      return (DrawableRequestBuilder<ModelType>) super.clone();
  }

  @Override
  public Target<GlideDrawable> into(ImageView view) {
      return super.into(view);
  }

  @Override
  void applyFitCenter() {
      fitCenter();
  }

  @Override
  void applyCenterCrop() {
      centerCrop();
  }
}

DrawableRequestBuilder父类GenericRequestBuilder
public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
      this.model = model;
      isModelSet = true;
      return this;
  }

}

into()路线分析

1.根据类型生成不同的target对象,在生成一个request请求

public Target<TranscodeType> into(ImageView view) {
  Util.assertMainThread();
  if (view == null) {
      throw new IllegalArgumentException("You must pass in a non null View");
  }
  if (!isTransformationSet && view.getScaleType() != null) {
      switch (view.getScaleType()) {
          case CENTER_CROP:
              applyCenterCrop();
              break;
          case FIT_CENTER:
          case FIT_START:
          case FIT_END:
              applyFitCenter();
              break;
          //$CASES-OMITTED$
          default:
              // Do nothing.
      }
  }
 //glide.buildImageViewTarget生成一个target并给Into方法
  return into(glide.buildImageViewTarget(view, transcodeClass));
}

//生成一个target对象
<R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
  return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}

public class ImageViewTargetFactory {

  @SuppressWarnings("unchecked")
  public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
//asBitmap()生成BitmapImageViewTarget
//其他大多数生成GlideDrawableImageViewTarget
      if (GlideDrawable.class.isAssignableFrom(clazz)) {
          return (Target<Z>) new GlideDrawableImageViewTarget(view);
      } else if (Bitmap.class.equals(clazz)) {
          return (Target<Z>) new BitmapImageViewTarget(view);
      } else if (Drawable.class.isAssignableFrom(clazz)) {
          return (Target<Z>) new DrawableImageViewTarget(view);
      } else {
          throw new IllegalArgumentException("Unhandled class: " + clazz
                  + ", try .as*(Class).transcode(ResourceTranscoder)");
      }
  }
}


//再根据target生成一个请求request
public <Y extends Target<TranscodeType>> Y into(Y target) {
  Util.assertMainThread();
  if (target == null) {
      throw new IllegalArgumentException("You must pass in a non null Target");
  }
  if (!isModelSet) {
      throw new IllegalArgumentException("You must first set a model (try #load())");
  }
  Request previous = target.getRequest();
  if (previous != null) {
      previous.clear();
      requestTracker.removeRequest(previous);
      previous.recycle();
  }
 //看看它是怎么生成我们request请求
  Request request = buildRequest(target);
  target.setRequest(request);
  lifecycle.addListener(target);
  requestTracker.runRequest(request);
  return target;
}

private Request buildRequest(Target<TranscodeType> target) {
  if (priority == null) {
      priority = Priority.NORMAL;
  }
 //又来到buildRequestRecursive
  return buildRequestRecursive(target, null);
}

//这个方法大部分都在处理缩略图,最后调用了obtainRequest
private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
  if (thumbnailRequestBuilder != 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()");
      }
      // Recursive case: contains a potentially recursive thumbnail request builder.
      if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
          thumbnailRequestBuilder.animationFactory = animationFactory;
      }

      if (thumbnailRequestBuilder.priority == null) {
          thumbnailRequestBuilder.priority = getThumbnailPriority();
      }

      if (Util.isValidDimensions(overrideWidth, overrideHeight)
              && !Util.isValidDimensions(thumbnailRequestBuilder.overrideWidth,
                      thumbnailRequestBuilder.overrideHeight)) {
        thumbnailRequestBuilder.override(overrideWidth, overrideHeight);
      }

      ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
      Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
      // Guard against infinite recursion.
      isThumbnailBuilt = true;
      // Recursively generate thumbnail requests.
      Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
      isThumbnailBuilt = false;
      coordinator.setRequests(fullRequest, thumbRequest);
      return coordinator;
  } else if (thumbSizeMultiplier != null) {
      // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
      ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
      Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
      Request thumbnailRequest = obtainRequest(target, thumbSizeMultiplier, getThumbnailPriority(), coordinator);
      coordinator.setRequests(fullRequest, thumbnailRequest);
      return coordinator;
  } else {
      // 没有缩略图的情况,调用obtainRequest
      return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
  }
}

//这个方法主要是把我们Glide的API的参数传给GenericRequest进行初始化
private Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
      RequestCoordinator requestCoordinator) {
  return GenericRequest.obtain(
          loadProvider,
          model,
          signature,
          context,
          priority,
          target,
          sizeMultiplier,
          placeholderDrawable,
          placeholderId,
          errorPlaceholder,
          errorId,
          fallbackDrawable,
          fallbackResource,
          requestListener,
          requestCoordinator,
          glide.getEngine(),
          transformation,
          transcodeClass,
          isCacheable,
          animationFactory,
          overrideWidth,
          overrideHeight,
          diskCacheStrategy);
}

//看看GenericRequest类
public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallback,
      ResourceCallback {

  ...

  public static <A, T, Z, R> GenericRequest<A, T, Z, R> obtain(
          LoadProvider<A, T, Z, R> loadProvider,
          A model,
          Key signature,
          Context context,
          Priority priority,
          Target<R> target,
          float sizeMultiplier,
          Drawable placeholderDrawable,
          int placeholderResourceId,
          Drawable errorDrawable,
          int errorResourceId,
          Drawable fallbackDrawable,
          int fallbackResourceId,
          RequestListener<? super A, R> requestListener,
          RequestCoordinator requestCoordinator,
          Engine engine,
          Transformation<Z> transformation,
          Class<R> transcodeClass,
          boolean isMemoryCacheable,
          GlideAnimationFactory<R> animationFactory,
          int overrideWidth,
          int overrideHeight,
          DiskCacheStrategy diskCacheStrategy) {
      @SuppressWarnings("unchecked")
      GenericRequest<A, T, Z, R> request = (GenericRequest<A, T, Z, R>) REQUEST_POOL.poll();
      if (request == null) {//生成一个GenericRequest对象
          request = new GenericRequest<A, T, Z, R>();
      }
//初始化赋值
      request.init(loadProvider,
              model,
              signature,
              context,
              priority,
              target,
              sizeMultiplier,
              placeholderDrawable,
              placeholderResourceId,
              errorDrawable,
              errorResourceId,
              fallbackDrawable,
              fallbackResourceId,
              requestListener,
              requestCoordinator,
              engine,
              transformation,
              transcodeClass,
              isMemoryCacheable,
              animationFactory,
              overrideWidth,
              overrideHeight,
              diskCacheStrategy);
      return request;
  }
  ...
}

2.request的执行流程通过网络请求:inputStream->bitmap->Resouce

//上面的into(target)的最后两行
public <Y extends Target<TranscodeType>> Y into(Y target) {
...
requestTracker.runRequest(request);
return target;
}

//此方法判断Glide是否处理暂停状态,否则调用request的begin()方法
public void runRequest(Request request) {
  requests.add(request);
  if (!isPaused) {
      request.begin();
  } else {
      pendingRequests.add(request);
  }
}

//看下GenericRequest的begin()方法
@Override
public void begin() {
  startTime = LogTime.getLogTime();
 //先判断传资源的路径是否为空,调用 onException(null)方法
  if (model == null) {
      onException(null);
      return;
  }
  status = Status.WAITING_FOR_SIZE;
 //如果调用API的override()确定了大小,直接走onSizeReady()方法,如果没有则调用getSize()确定大小之后再调用onSizeReady()方法。
  if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
  } else {
      target.getSize(this);
  }
 //开始请求但是没有完成请求时,调用Placeholder占位图显示在控件上
  if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
      target.onLoadStarted(getPlaceholderDrawable());
  }
  if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logV("finished run method in " + LogTime.getElapsedMillis(startTime));
  }
}

//当资源路径为空时:
private void setErrorPlaceholder(Exception e) {
  if (!canNotifyStatusChanged()) {
      return;
  }
  Drawable error = model == null ? getFallbackDrawable() : null;
 //找errror()的占位图
  if (error == null) {
    error = getErrorDrawable();
  }
 //error()找不到再找Placeholder占位图
  if (error == null) {
      error = getPlaceholderDrawable();
  }
 //把失败的图片显示出来
  target.onLoadFailed(e, error);
}

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

  ...

  @Override
  public void onLoadStarted(Drawable placeholder) {
      view.setImageDrawable(placeholder);
  }

  @Override
  public void onLoadFailed(Exception e, Drawable errorDrawable) {
      view.setImageDrawable(errorDrawable);
  }

  ...
}

//当资源路径不为空,并且确定好view的大小后
@Override
  public void onSizeReady(int width, int height) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
      }
      if (status != Status.WAITING_FOR_SIZE) {
          return;
      }
      status = Status.RUNNING;

      width = Math.round(sizeMultiplier * width);
      height = Math.round(sizeMultiplier * height);
     //重点一:loadProvider.getModelLoader(),这里的loadProvider是在DrawableTypeRequest中创建的。返回拿到ImageVideoModelLoader
     //得到ImageVideoModelLoader
      ModelLoader<A, T> modelLoader = loadProvider.getModelLoader();
     //得到的是一个ImageVideoFetcher
      final DataFetcher<T> dataFetcher = modelLoader.getResourceFetcher(model, width, height);

      if (dataFetcher == null) {
          onException(new Exception("Failed to load model: \'" + model + "\'"));
          return;
      }
     //的带GifBitmapWrapperDrawableTranscoder的图片转码GifBitmapWrapperDrawableTranscoder
      ResourceTranscoder<Z, R> transcoder = loadProvider.getTranscoder();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
      }
      loadedFromMemoryCache = true;
       //最终调用Engine.load()方法
      loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
              priority, isMemoryCacheable, diskCacheStrategy, this);
      loadedFromMemoryCache = resource != null;
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
      }
  }

//看看DrawableTypeRequest是如何创建loadProvider
public class DrawableTypeRequest<ModelType> extends DrawableRequestBuilder<ModelType> implements DownloadOptions {

  private final ModelLoader<ModelType, InputStream> streamModelLoader;
  private final ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader;
  private final RequestManager.OptionsApplier optionsApplier;

  private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(Glide glide,
          ModelLoader<A, InputStream> streamModelLoader,
          ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, Class<Z> resourceClass,
          Class<R> transcodedClass,
          ResourceTranscoder<Z, R> transcoder) {
      if (streamModelLoader == null && fileDescriptorModelLoader == null) {
          return null;
      }
      //glide.buildTranscoder()方法来构建一个ResourceTranscoder,它是用于对图片进行转码的,
//由于ResourceTranscoder是一个接口,这里实际会构建出一个GifBitmapWrapperDrawableTranscoder对象
      if (transcoder == null) {
          transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
      }
//glide.buildDataProvider()方法来构建一个DataLoadProvider,它是用于对图片进行编解码的,
//由于DataLoadProvider是一个接口,这里实际会构建出一个ImageVideoGifDrawableLoadProvider对象。
      DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
              resourceClass);
//new了一个ImageVideoModelLoader的实例,并把之前loadGeneric()方法中构建的两个ModelLoader封装到了ImageVideoModelLoader当中
      ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
              fileDescriptorModelLoader);
//new出一个FixedLoadProvider,并把刚才构建的出来的GifBitmapWrapperDrawableTranscoder、ImageVideoModelLoader、ImageVideoGifDrawableLoadProvider都封装进去
      return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
  }

  DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
          ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
          RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
     //在构造方法中,调用buildProvider()方法,并将其返回的对象传给requestBuilder
      super(context, modelClass,
              buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, GifBitmapWrapper.class,
                      GlideDrawable.class, null),
              glide, requestTracker, lifecycle);
      this.streamModelLoader = streamModelLoader;
      this.fileDescriptorModelLoader = fileDescriptorModelLoader;
      this.optionsApplier = optionsApplier;
  }
  ...
}

再看看onSizeReady()用到loadProvider的代码:
@Override
public void onSizeReady(int width, int height) {
//拿到ImageVideoModelLoader
  ModelLoader<A, T> modelLoader = loadProvider.getModelLoader();
 //调用ImageVideoModelLoader.getResourceFetcher(),得到的是一个ImageVideoFetcher
  final DataFetcher<T> dataFetcher = modelLoader.getResourceFetcher(model, width, height);
  if (dataFetcher == null) {
      onException(new Exception("Failed to load model: \'" + model + "\'"));
      return;
  }
  //拿到GifBitmapWrapperDrawableTranscoder的图片转码
  ResourceTranscoder<Z, R> transcoder = loadProvider.getTranscoder();

}


public class ImageVideoModelLoader<A> implements ModelLoader<A, ImageVideoWrapper> {
  private static final String TAG = "IVML";

  private final ModelLoader<A, InputStream> streamLoader;
  private final ModelLoader<A, ParcelFileDescriptor> fileDescriptorLoader;
  public ImageVideoModelLoader(ModelLoader<A, InputStream> streamLoader,
          ModelLoader<A, ParcelFileDescriptor> fileDescriptorLoader) {
      if (streamLoader == null && fileDescriptorLoader == null) {
          throw new NullPointerException("At least one of streamLoader and fileDescriptorLoader must be non null");
      }
      this.streamLoader = streamLoader;
      this.fileDescriptorLoader = fileDescriptorLoader;
  }

  @Override
  public DataFetcher<ImageVideoWrapper> getResourceFetcher(A model, int width, int height) {
      DataFetcher<InputStream> streamFetcher = null;
      if (streamLoader != null) {
          //获取一个HttpUrlFetcher对象。streamLoader其实就是我们在loadGeneric()方法中构建出的StreamStringLoader
          streamFetcher = streamLoader.getResourceFetcher(model, width, height);
      }

      DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher = null;
      if (fileDescriptorLoader != null) {
          fileDescriptorFetcher = fileDescriptorLoader.getResourceFetcher(model, width, height);
      }

      if (streamFetcher != null || fileDescriptorFetcher != null) {
         //最后返回一个ImageVideoFetcher对象
          return new ImageVideoFetcher(streamFetcher, fileDescriptorFetcher);
      } else {
          return null;
      }
  }

  static class ImageVideoFetcher implements DataFetcher<ImageVideoWrapper> {
      private final DataFetcher<InputStream> streamFetcher;
      private final DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher;

      public ImageVideoFetcher(DataFetcher<InputStream> streamFetcher,
              DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher) {
          this.streamFetcher = streamFetcher;
          this.fileDescriptorFetcher = fileDescriptorFetcher;
      }

      ...
  }
}

onSizeReady()继续下一步调用Engine的load(),
并把得到ImageVideoFetcher、GifBitmapWrapperDrawableTranscoder等传入到了Engine的load()方法当中。

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

  ...    

  public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
          DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
          Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
      Util.assertMainThread();
      long startTime = LogTime.getLogTime();

      final String id = fetcher.getId();
      EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
              loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
              transcoder, loadProvider.getSourceEncoder());
       //都是处理缓存问题
      EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
      if (cached != null) {
          cb.onResourceReady(cached);
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
              logWithTimeAndKey("Loaded resource from cache", startTime, key);
          }
          return null;
      }

      EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
      if (active != null) {
          cb.onResourceReady(active);
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
              logWithTimeAndKey("Loaded resource from active resources", startTime, key);
          }
          return null;
      }

      EngineJob current = jobs.get(key);
      if (current != null) {
          current.addCallback(cb);
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
              logWithTimeAndKey("Added to existing load", startTime, key);
          }
          return new LoadStatus(cb, current);
      }
      //从这里重点看起
      //构建了一个EngineJob,它的主要作用就是用来开启线程的,为后面的异步加载图片做准备。
      EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
      //DecodeJob对象,它好像是用来对图片进行解码的,但实际上它的任务十分繁重。
      DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
              transcoder, diskCacheProvider, diskCacheStrategy, priority);
      //创建了一个EngineRunnable对象
      EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
      jobs.put(key, engineJob);
      engineJob.addCallback(cb);
      engineJob.start(runnable);//调用了EngineJob的start()方法来运行EngineRunnable对象

      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          logWithTimeAndKey("Started new load", startTime, key);
      }
      return new LoadStatus(cb, engineJob);
  }

  ...
}


看看EngineRunnable的run()到底在异步执行什么?
@Override
public void run() {
  if (isCancelled) {
      return;
  }
  Exception exception = null;
  Resource<?> resource = null;
  try {
      //主要是调用了decode()方法得到resource
      resource = decode();
  } catch (Exception e) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          Log.v(TAG, "Exception decoding", e);
      }
      exception = e;
  }
  if (isCancelled) {
      if (resource != null) {
          resource.recycle();
      }
      return;
  }
  if (resource == null) {
      onLoadFailed(exception);
  } else {
      onLoadComplete(resource);
  }
}

private Resource<?> decode() throws Exception {
 //是否从缓存中拿
  if (isDecodingFromCache()) {
      return decodeFromCache();
  } else {
      //看看没有缓存的情况,怎么拿source
      return decodeFromSource();
  }
}

private Resource<?> decodeFromSource() throws Exception {
   //跳到了decodeJob.decodeFromSource()方法
  return decodeJob.decodeFromSource();
}

class DecodeJob<A, T, Z> {

  ...
  //拿到
  public Resource<Z> decodeFromSource() throws Exception {
     //调用decodeSource()方法拿到了Resource
      Resource<T> decoded = decodeSource();
      //通过transformEncodeAndTranscode处理并返回Resource
      return transformEncodeAndTranscode(decoded);
  }

 //拿到带有InputStream的ImageVideoWrapper对象,进行解码并返回Resource
  private Resource<T> decodeSource() throws Exception {
      Resource<T> decoded = null;
      try {
          long startTime = LogTime.getLogTime();
          //重点在这里,ImageVideoFetcher对象,这里调用它的loadData()方法
          final A data = fetcher.loadData(priority);
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
              logWithTimeAndKey("Fetched data", startTime);
          }
          if (isCancelled) {
              return null;
          }
          //调用decodeFromSourceData()生成Resource
          decoded = decodeFromSourceData(data);
      } finally {
          fetcher.cleanup();
      }
      return decoded;
  }
  ...
}


static class ImageVideoFetcher implements DataFetcher<ImageVideoWrapper> {
      private final DataFetcher<InputStream> streamFetcher;
      private final DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher;

      public ImageVideoFetcher(DataFetcher<InputStream> streamFetcher,
              DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher) {
          this.streamFetcher = streamFetcher;
          this.fileDescriptorFetcher = fileDescriptorFetcher;
      }

通过网络请求拿到inputStream,并创建一个ImageVideoWrapper对象返回给DecodeJob.decodeSource()
@Override
      public ImageVideoWrapper loadData(Priority priority) throws Exception {
          InputStream is = null;
          if (streamFetcher != null) {
              try {
                  //重点是这里拿到InputStream,streamFetcher是创建对象得一个人参数HttpUrlFetcher
                  is = streamFetcher.loadData(priority);
              } catch (Exception e) {
                  if (Log.isLoggable(TAG, Log.VERBOSE)) {
                      Log.v(TAG, "Exception fetching input stream, trying ParcelFileDescriptor", e);
                  }
                  if (fileDescriptorFetcher == null) {
                      throw e;
                  }
              }
          }
          ParcelFileDescriptor fileDescriptor = null;
          if (fileDescriptorFetcher != null) {
              try {
                  fileDescriptor = fileDescriptorFetcher.loadData(priority);
              } catch (Exception e) {
                  if (Log.isLoggable(TAG, Log.VERBOSE)) {
                      Log.v(TAG, "Exception fetching ParcelFileDescriptor", e);
                  }
                  if (is == null) {
                      throw e;
                  }
              }
          }
         //拿到网络请求得InputStream并创建ImageVideoWrapper对象,返回给DecodeJob.decodeSource()生成Resource
          return new ImageVideoWrapper(is, fileDescriptor);
      }


这个类名一看就是进行网络请求了,并放回InputStream 给ImageVideoFetcher
public class HttpUrlFetcher implements DataFetcher<InputStream> {

  ...

  @Override
  public InputStream loadData(Priority priority) throws Exception {
     // 调用loadDataWithRedirects()
      return loadDataWithRedirects(glideUrl.toURL(), 0 /*redirects*/, null /*lastUrl*/, glideUrl.getHeaders());
  }

  private InputStream loadDataWithRedirects(URL url, int redirects, URL lastUrl, Map<String, String> headers)
          throws IOException {
      if (redirects >= MAXIMUM_REDIRECTS) {
          throw new IOException("Too many (> " + MAXIMUM_REDIRECTS + ") redirects!");
      } else {
          // Comparing the URLs using .equals performs additional network I/O and is generally broken.
          // See http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html.
          try {
              if (lastUrl != null && url.toURI().equals(lastUrl.toURI())) {
                  throw new IOException("In re-direct loop");
              }
          } catch (URISyntaxException e) {
              // Do nothing, this is best effort.
          }
      }
      urlConnection = connectionFactory.build(url);
      for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
        urlConnection.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
      }
      urlConnection.setConnectTimeout(2500);
      urlConnection.setReadTimeout(2500);
      urlConnection.setUseCaches(false);
      urlConnection.setDoInput(true);

      // Connect explicitly to avoid errors in decoders if connection fails.
      urlConnection.connect();
      if (isCancelled) {
          return null;
      }
      final int statusCode = urlConnection.getResponseCode();
      if (statusCode / 100 == 2) {
          return getStreamForSuccessfulRequest(urlConnection);
      } else if (statusCode / 100 == 3) {
          String redirectUrlString = urlConnection.getHeaderField("Location");
          if (TextUtils.isEmpty(redirectUrlString)) {
              throw new IOException("Received empty or null redirect url");
          }
          URL redirectUrl = new URL(url, redirectUrlString);
          return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
      } else {
          if (statusCode == -1) {
              throw new IOException("Unable to retrieve response code from HttpUrlConnection.");
          }
          throw new IOException("Request failed " + statusCode + ": " + urlConnection.getResponseMessage());
      }
  }

  private InputStream getStreamForSuccessfulRequest(HttpURLConnection urlConnection)
          throws IOException {
      if (TextUtils.isEmpty(urlConnection.getContentEncoding())) {
          int contentLength = urlConnection.getContentLength();
          stream = ContentLengthInputStream.obtain(urlConnection.getInputStream(), contentLength);
      } else {
          if (Log.isLoggable(TAG, Log.DEBUG)) {
              Log.d(TAG, "Got non empty content encoding: " + urlConnection.getContentEncoding());
          }
          stream = urlConnection.getInputStream();
      }
      return stream;
  }

  ...
}

我们再看看DecodeJob.decodeSource()方法得到inputStream会怎么走生成Resource
private Resource<T> decodeSource() throws Exception {
//调用decodeFromSourceData()进行解码生成Resource
decoded = decodeFromSourceData(data);
...
return decoded;
}

private Resource<T> decodeFromSourceData(A data) throws IOException {
  final Resource<T> decoded;
  if (diskCacheStrategy.cacheSource()) {
      decoded = cacheAndDecodeSourceData(data);
  } else {
      long startTime = LogTime.getLogTime();
      //GifBitmapWrapperResourceDecoder.decode进行解码
      decoded = loadProvider.getSourceDecoder().decode(data, width, height);
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          logWithTimeAndKey("Decoded from source", startTime);
      }
  }
  return decoded;
}


public class GifBitmapWrapperResourceDecoder implements ResourceDecoder<ImageVideoWrapper, GifBitmapWrapper> {

  ...

  @SuppressWarnings("resource")
  // @see ResourceDecoder.decode
  @Override
 //先拿到bitmap再对bitmap进行封装存储
 经过这一层的封装之后,我们从网络上得到的图片就能够以Resource接口的形式返回,并且还能同时处理Bitmap图片和GIF图片这两种情况。
  public Resource<GifBitmapWrapper> decode(ImageVideoWrapper source, int width, int height) throws IOException {
      ByteArrayPool pool = ByteArrayPool.get();
      byte[] tempBytes = pool.getBytes();
      GifBitmapWrapper wrapper = null;
      try {
         //调用重载的decode()
          wrapper = decode(source, width, height, tempBytes);
      } finally {
          pool.releaseBytes(tempBytes);
      }
      return wrapper != null ? new GifBitmapWrapperResource(wrapper) : null;
  }

调用decodeStream()方法,准备从服务器返回的流当中读取数据
  private GifBitmapWrapper decode(ImageVideoWrapper source, int width, int height, byte[] bytes) throws IOException {
      final GifBitmapWrapper result;
      if (source.getStream() != null) {
          result = decodeStream(source, width, height, bytes);
      } else {
          result = decodeBitmapWrapper(source, width, height);
      }
      return result;
  }

 decodeStream()方法中会先从流中读取2个字节的数据,来判断这张图是GIF图还是普通的静图,
 如果是GIF图就调用decodeGifWrapper()方法来进行解码,
 如果是普通的静图就用调用decodeBitmapWrapper()方法来进行解码
  private GifBitmapWrapper decodeStream(ImageVideoWrapper source, int width, int height, byte[] bytes)
          throws IOException {
      InputStream bis = streamFactory.build(source.getStream(), bytes);
      bis.mark(MARK_LIMIT_BYTES);
      ImageHeaderParser.ImageType type = parser.parse(bis);
      bis.reset();
      GifBitmapWrapper result = null;
      //是gif动图
      if (type == ImageHeaderParser.ImageType.GIF) {
          result = decodeGifWrapper(bis, width, height);
      }
      // Decoding the gif may fail even if the type matches.
      //是静态图
      if (result == null) {
          // We can only reset the buffered InputStream, so to start from the beginning of the stream, we need to
          // pass in a new source containing the buffered stream rather than the original stream.
          ImageVideoWrapper forBitmapDecoder = new ImageVideoWrapper(bis, source.getFileDescriptor());
          result = decodeBitmapWrapper(forBitmapDecoder, width, height);
      }
      return result;
  }

  //先拿到bitmap,然后再把bitmap封装到GifBitmapWrapper中
  private GifBitmapWrapper decodeBitmapWrapper(ImageVideoWrapper toDecode, int width, int height) throws IOException {
      GifBitmapWrapper result = null;
      //ImageVideoBitmapDecoder.decode()进行解析
      Resource<Bitmap> bitmapResource = bitmapDecoder.decode(toDecode, width, height);
      if (bitmapResource != null) {
          result = new GifBitmapWrapper(bitmapResource, null);
      }
      return result;
  }
  ...
}


public class ImageVideoBitmapDecoder implements ResourceDecoder<ImageVideoWrapper, Bitmap> {
  private final ResourceDecoder<InputStream, Bitmap> streamDecoder;
  private final ResourceDecoder<ParcelFileDescriptor, Bitmap> fileDescriptorDecoder;

  public ImageVideoBitmapDecoder(ResourceDecoder<InputStream, Bitmap> streamDecoder,
          ResourceDecoder<ParcelFileDescriptor, Bitmap> fileDescriptorDecoder) {
      this.streamDecoder = streamDecoder;
      this.fileDescriptorDecoder = fileDescriptorDecoder;
  }

  @Override
  public Resource<Bitmap> decode(ImageVideoWrapper source, int width, int height) throws IOException {
      Resource<Bitmap> result = null;
      //先拿到服务器返回的InputStream
      InputStream is = source.getStream();
      if (is != null) {
          try {
               //对InputStream进行解码,调用StreamBitmapDecoder.decode()
              result = streamDecoder.decode(is, width, height);
          } catch (IOException e) {
              if (Log.isLoggable(TAG, Log.VERBOSE)) {
                  Log.v(TAG, "Failed to load image from stream, trying FileDescriptor", e);
              }
          }
      }
      if (result == null) {
          ParcelFileDescriptor fileDescriptor = source.getFileDescriptor();
          if (fileDescriptor != null) {
              result = fileDescriptorDecoder.decode(fileDescriptor, width, height);
          }
      }
      return result;
  }

  ...
}


public class StreamBitmapDecoder implements ResourceDecoder<InputStream, Bitmap> {

  ...

  private final Downsampler downsampler;
  private BitmapPool bitmapPool;
  private DecodeFormat decodeFormat;

  public StreamBitmapDecoder(Downsampler downsampler, BitmapPool bitmapPool, DecodeFormat decodeFormat) {
      this.downsampler = downsampler;
      this.bitmapPool = bitmapPool;
      this.decodeFormat = decodeFormat;
  }

 //拿到Bitmap后,将Bitmap对象包装成了Resource<Bitmap>对象
  @Override
  public Resource<Bitmap> decode(InputStream source, int width, int height) {
      Bitmap bitmap = downsampler.decode(source, bitmapPool, width, height, decodeFormat);
      return BitmapResource.obtain(bitmap, bitmapPool);
  }

  ...
}

//对bitmap进行封装存储
public class BitmapResource implements Resource<Bitmap> {
  private final Bitmap bitmap;
  private final BitmapPool bitmapPool;

  /**
   * Returns a new {@link BitmapResource} wrapping the given {@link Bitmap} if the Bitmap is non-null or null if the
   * given Bitmap is null.
   *
   * @param bitmap A Bitmap.
   * @param bitmapPool A non-null {@link BitmapPool}.
   */
  public static BitmapResource obtain(Bitmap bitmap, BitmapPool bitmapPool) {
      if (bitmap == null) {
          return null;
      } else {
          return new BitmapResource(bitmap, bitmapPool);
      }
  }

  public BitmapResource(Bitmap bitmap, BitmapPool bitmapPool) {
      if (bitmap == null) {
          throw new NullPointerException("Bitmap must not be null");
      }
      if (bitmapPool == null) {
          throw new NullPointerException("BitmapPool must not be null");
      }
      this.bitmap = bitmap;
      this.bitmapPool = bitmapPool;
  }

  @Override
  public Bitmap get() {
      return bitmap;
  }

  @Override
  public int getSize() {
      return Util.getBitmapByteSize(bitmap);
  }

  @Override
  public void recycle() {
      if (!bitmapPool.put(bitmap)) {
          bitmap.recycle();
      }
  }
}


//返回bitmap
public abstract class Downsampler implements BitmapDecoder<InputStream> {

  ...
   对服务器返回的InputStream的读取,以及对图片的加载全都在这里了。当然这里其实处理了很多的逻辑,包括对图片的压缩,甚至还有旋转、圆角等逻辑处理。
decode()方法执行之后,会返回一个Bitmap对象。剩下的工作就是如果让这个Bitmap显示到界面上
  @Override
  public Bitmap decode(InputStream is, BitmapPool pool, int outWidth, int outHeight, DecodeFormat decodeFormat) {
      final ByteArrayPool byteArrayPool = ByteArrayPool.get();
      final byte[] bytesForOptions = byteArrayPool.getBytes();
      final byte[] bytesForStream = byteArrayPool.getBytes();
      final BitmapFactory.Options options = getDefaultOptions();
      // Use to fix the mark limit to avoid allocating buffers that fit entire images.
      RecyclableBufferedInputStream bufferedStream = new RecyclableBufferedInputStream(
              is, bytesForStream);
      // Use to retrieve exceptions thrown while reading.
      // TODO(#126): when the framework no longer returns partially decoded Bitmaps or provides a way to determine
      // if a Bitmap is partially decoded, consider removing.
      ExceptionCatchingInputStream exceptionStream =
              ExceptionCatchingInputStream.obtain(bufferedStream);
      // Use to read data.
      // Ensures that we can always reset after reading an image header so that we can still attempt to decode the
      // full image even when the header decode fails and/or overflows our read buffer. See #283.
      MarkEnforcingInputStream invalidatingStream = new MarkEnforcingInputStream(exceptionStream);
      try {
          exceptionStream.mark(MARK_POSITION);
          int orientation = 0;
          try {
              orientation = new ImageHeaderParser(exceptionStream).getOrientation();
          } catch (IOException e) {
              if (Log.isLoggable(TAG, Log.WARN)) {
                  Log.w(TAG, "Cannot determine the image orientation from header", e);
              }
          } finally {
              try {
                  exceptionStream.reset();
              } catch (IOException e) {
                  if (Log.isLoggable(TAG, Log.WARN)) {
                      Log.w(TAG, "Cannot reset the input stream", e);
                  }
              }
          }
          options.inTempStorage = bytesForOptions;
          final int[] inDimens = getDimensions(invalidatingStream, bufferedStream, options);
          final int inWidth = inDimens[0];
          final int inHeight = inDimens[1];
          final int degreesToRotate = TransformationUtils.getExifOrientationDegrees(orientation);
          final int sampleSize = getRoundedSampleSize(degreesToRotate, inWidth, inHeight, outWidth, outHeight);
          final Bitmap downsampled =
                  downsampleWithSize(invalidatingStream, bufferedStream, options, pool, inWidth, inHeight, sampleSize,
                          decodeFormat);
          // BitmapFactory swallows exceptions during decodes and in some cases when inBitmap is non null, may catch
          // and log a stack trace but still return a non null bitmap. To avoid displaying partially decoded bitmaps,
          // we catch exceptions reading from the stream in our ExceptionCatchingInputStream and throw them here.
          final Exception streamException = exceptionStream.getException();
          if (streamException != null) {
              throw new RuntimeException(streamException);
          }
          Bitmap rotated = null;
          if (downsampled != null) {
              rotated = TransformationUtils.rotateImageExif(downsampled, pool, orientation);
              if (!downsampled.equals(rotated) && !pool.put(downsampled)) {
                  downsampled.recycle();
              }
          }
          return rotated;
      } finally {
          byteArrayPool.releaseBytes(bytesForOptions);
          byteArrayPool.releaseBytes(bytesForStream);
          exceptionStream.release();
          releaseOptions(options);
      }
  }

  private Bitmap downsampleWithSize(MarkEnforcingInputStream is, RecyclableBufferedInputStream  bufferedStream,
          BitmapFactory.Options options, BitmapPool pool, int inWidth, int inHeight, int sampleSize,
          DecodeFormat decodeFormat) {
      // Prior to KitKat, the inBitmap size must exactly match the size of the bitmap we're decoding.
      Bitmap.Config config = getConfig(is, decodeFormat);
      options.inSampleSize = sampleSize;
      options.inPreferredConfig = config;
      if ((options.inSampleSize == 1 || Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) && shouldUsePool(is)) {
          int targetWidth = (int) Math.ceil(inWidth / (double) sampleSize);
          int targetHeight = (int) Math.ceil(inHeight / (double) sampleSize);
          // BitmapFactory will clear out the Bitmap before writing to it, so getDirty is safe.
          setInBitmap(options, pool.getDirty(targetWidth, targetHeight, config));
      }
      return decodeStream(is, bufferedStream, options);
  }

  /**
   * A method for getting the dimensions of an image from the given InputStream.
   *
   * @param is The InputStream representing the image.
   * @param options The options to pass to
   *          {@link BitmapFactory#decodeStream(InputStream, android.graphics.Rect,
   *              BitmapFactory.Options)}.
   * @return an array containing the dimensions of the image in the form {width, height}.
   */
  public int[] getDimensions(MarkEnforcingInputStream is, RecyclableBufferedInputStream bufferedStream,
          BitmapFactory.Options options) {
      options.inJustDecodeBounds = true;
      decodeStream(is, bufferedStream, options);
      options.inJustDecodeBounds = false;
      return new int[] { options.outWidth, options.outHeight };
  }

  private static Bitmap decodeStream(MarkEnforcingInputStream is, RecyclableBufferedInputStream bufferedStream,
          BitmapFactory.Options options) {
       if (options.inJustDecodeBounds) {
           // This is large, but jpeg headers are not size bounded so we need something large enough to minimize
           // the possibility of not being able to fit enough of the header in the buffer to get the image size so
           // that we don't fail to load images. The BufferedInputStream will create a new buffer of 2x the
           // original size each time we use up the buffer space without passing the mark so this is a maximum
           // bound on the buffer size, not a default. Most of the time we won't go past our pre-allocated 16kb.
           is.mark(MARK_POSITION);
       } else {
           // Once we've read the image header, we no longer need to allow the buffer to expand in size. To avoid
           // unnecessary allocations reading image data, we fix the mark limit so that it is no larger than our
           // current buffer size here. See issue #225.
           bufferedStream.fixMarkLimit();
       }
      final Bitmap result = BitmapFactory.decodeStream(is, null, options);
      try {
          if (options.inJustDecodeBounds) {
              is.reset();
          }
      } catch (IOException e) {
          if (Log.isLoggable(TAG, Log.ERROR)) {
              Log.e(TAG, "Exception loading inDecodeBounds=" + options.inJustDecodeBounds
                      + " sample=" + options.inSampleSize, e);
          }
      }

      return result;
  }

  ...
}

3.请求后得到的Resource怎么处理

class DecodeJob{
得到请求返回的Resource后,调用transformEncodeAndTranscode()返回Resource<Z>
public Resource<Z> decodeFromSource() throws Exception {
  Resource<T> decoded = decodeSource();
  return transformEncodeAndTranscode(decoded);
}

private Resource<Z> transformEncodeAndTranscode(Resource<T> decoded) {
  long startTime = LogTime.getLogTime();
  Resource<T> transformed = transform(decoded);
  if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Transformed resource from source", startTime);
  }
  writeTransformedToCache(transformed);
  startTime = LogTime.getLogTime();
  //GifBitmapWrapperDrawableTranscoder.transcode()方法
  Resource<Z> result = transcode(transformed);
  if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logWithTimeAndKey("Transcoded transformed from source", startTime);
  }
  return result;
}

private Resource<Z> transcode(Resource<T> transformed) {
  if (transformed == null) {
      return null;
  }
  return transcoder.transcode(transformed);
}
}

public class GifBitmapWrapperDrawableTranscoder implements ResourceTranscoder<GifBitmapWrapper, GlideDrawable> {
  private final ResourceTranscoder<Bitmap, GlideBitmapDrawable> bitmapDrawableResourceTranscoder;

  public GifBitmapWrapperDrawableTranscoder(
          ResourceTranscoder<Bitmap, GlideBitmapDrawable> bitmapDrawableResourceTranscoder) {
      this.bitmapDrawableResourceTranscoder = bitmapDrawableResourceTranscoder;
  }
//GifBitmapWrapperDrawableTranscoder的核心作用就是用来转码的。
//因为GifBitmapWrapper是无法直接显示到ImageView上面的,只有Bitmap或者Drawable才能显示到ImageView上。

//这里的transcode()方法先从Resource<GifBitmapWrapper>中取出GifBitmapWrapper对象,
//然后再从GifBitmapWrapper中取出Resource<Bitmap>对象。
//如果Resource<Bitmap>为空,那么说明此时加载的是GIF图,直接调用getGifResource()方法将图片取出即可,
//而如果Resource<Bitmap>不为空,那么就需要再做一次转码,将Bitmap转换成Drawable对象才行。
  @Override
  public Resource<GlideDrawable> transcode(Resource<GifBitmapWrapper> toTranscode) {
      GifBitmapWrapper gifBitmap = toTranscode.get();
      Resource<Bitmap> bitmapResource = gifBitmap.getBitmapResource();
      final Resource<? extends GlideDrawable> result;
      if (bitmapResource != null) {
          result = bitmapDrawableResourceTranscoder.transcode(bitmapResource);
      } else {
          result = gifBitmap.getGifResource();
      }
      return (Resource<GlideDrawable>) result;
  }

  ...
}

//对于静态图再次转码:
public class GlideBitmapDrawableTranscoder implements ResourceTranscoder<Bitmap, GlideBitmapDrawable> {
  private final Resources resources;
  private final BitmapPool bitmapPool;

  public GlideBitmapDrawableTranscoder(Context context) {
      this(context.getResources(), Glide.get(context).getBitmapPool());
  }

  public GlideBitmapDrawableTranscoder(Resources resources, BitmapPool bitmapPool) {
      this.resources = resources;
      this.bitmapPool = bitmapPool;
  }

  @Override
  public Resource<GlideBitmapDrawable> transcode(Resource<Bitmap> toTranscode) {
   //进行两次封装
      GlideBitmapDrawable drawable = new GlideBitmapDrawable(resources, toTranscode.get());
      return new GlideBitmapDrawableResource(drawable, bitmapPool);
  }

  ...
}

得到Resource之后,我们来看看EngineRunnable的run()方法:
@Override
public void run() {
  if (isCancelled) {
      return;
  }
  Exception exception = null;
  Resource<?> resource = null;
  try {
     //最终得到了Resource<GlideDrawable>
      resource = decode();
  } catch (Exception e) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          Log.v(TAG, "Exception decoding", e);
      }
      exception = e;
  }
  if (isCancelled) {
      if (resource != null) {
          resource.recycle();
      }
      return;
  }
  if (resource == null) {
      onLoadFailed(exception);
  } else {
      //如果资源不为空,调用加载完成的方法
      onLoadComplete(resource);
  }
}

private void onLoadComplete(Resource resource) {
//EngineJob.onResourceReady
  manager.onResourceReady(resource);
}

class EngineJob implements EngineRunnable.EngineRunnableManager {

  private static final Handler MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper(), new MainThreadCallback());

  private final List<ResourceCallback> cbs = new ArrayList<ResourceCallback>();

  ...
  //这里的addCallback在Engine.load中调用,并把GenericRequest传进去
  public void addCallback(ResourceCallback cb) {
      Util.assertMainThread();
      if (hasResource) {
          cb.onResourceReady(engineResource);
      } else if (hasException) {
          cb.onException(exception);
      } else {
          cbs.add(cb);
      }
  }

  @Override
  public void onResourceReady(final Resource<?> resource) {
      this.resource = resource;
      //使用Handler发出了一条MSG_COMPLETE消息MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
  }

//把线程切换到UI进行操作,不断的遍历ResourceCallback集合,最终调用GenericRequest.onResourceReady()方法
  private void handleResultOnMainThread() {
      if (isCancelled) {
          resource.recycle();
          return;
      } else if (cbs.isEmpty()) {
          throw new IllegalStateException("Received a resource without any callbacks to notify");
      }
      engineResource = engineResourceFactory.build(resource, isCacheable);
      hasResource = true;
      engineResource.acquire();
      listener.onEngineJobComplete(key, engineResource);
      for (ResourceCallback cb : cbs) {
          if (!isInIgnoredCallbacks(cb)) {
              engineResource.acquire();
              cb.onResourceReady(engineResource);
          }
      }
      engineResource.release();
  }

  @Override
  public void onException(final Exception e) {
      this.exception = e;
      MAIN_THREAD_HANDLER.obtainMessage(MSG_EXCEPTION, this).sendToTarget();
  }

  private void handleExceptionOnMainThread() {
      if (isCancelled) {
          return;
      } else if (cbs.isEmpty()) {
          throw new IllegalStateException("Received an exception without any callbacks to notify");
      }
      hasException = true;
      listener.onEngineJobComplete(key, null);
      for (ResourceCallback cb : cbs) {
          if (!isInIgnoredCallbacks(cb)) {
              cb.onException(exception);
          }
      }
  }

  private static class MainThreadCallback implements Handler.Callback {

      @Override
      public boolean handleMessage(Message message) {
          if (MSG_COMPLETE == message.what || MSG_EXCEPTION == message.what) {
              EngineJob job = (EngineJob) message.obj;
              if (MSG_COMPLETE == message.what) {
                  job.handleResultOnMainThread();
              } else {
                  job.handleExceptionOnMainThread();
              }
              return true;
          }
          return false;
      }
  }

  ...
}

public void onResourceReady(Resource<?> resource) {
  if (resource == null) {
      onException(new Exception("Expected to receive a Resource<R> with an object of " + transcodeClass
              + " inside, but instead got null."));
      return;
  }
 //调用resource.get()方法获取到了封装的图片对象,GlideBitmapDrawable对象,或者是GifDrawable对象
  Object received = resource.get();
  if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
      releaseResource(resource);
      onException(new Exception("Expected to receive an object of " + transcodeClass
              + " but instead got " + (received != null ? received.getClass() : "") + "{" + received + "}"
              + " inside Resource{" + resource + "}."
              + (received != null ? "" : " "
                  + "To indicate failure return a null Resource object, "
                  + "rather than a Resource object containing null data.")
      ));
      return;
  }
  if (!canSetResource()) {
      releaseResource(resource);
      // We can't set the status to complete before asking canSetResource().
      status = Status.COMPLETE;
      return;
  }
//传到下一个onResourceReady()
  onResourceReady(resource, (R) received);
}

private void onResourceReady(Resource<?> resource, R result) {
  // We must call isFirstReadyResource before setting status.
  boolean isFirstResource = isFirstReadyResource();
  status = Status.COMPLETE;
  this.resource = resource;
  if (requestListener == null || !requestListener.onResourceReady(result, model, target, loadedFromMemoryCache,
          isFirstResource)) {
      GlideAnimation<R> animation = animationFactory.build(loadedFromMemoryCache, isFirstResource);
      //GlideDrawableImageViewTarget.onResourceReady()
      target.onResourceReady(result, animation);
  }
  notifyLoadSuccess();
  if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logV("Resource ready in " + LogTime.getElapsedMillis(startTime) + " size: "
              + (resource.getSize() * TO_MEGABYTE) + " fromCache: " + loadedFromMemoryCache);
  }
}

public class GlideDrawableImageViewTarget extends ImageViewTarget<GlideDrawable> {
  private static final float SQUARE_RATIO_MARGIN = 0.05f;
  private int maxLoopCount;
  private GlideDrawable resource;

  public GlideDrawableImageViewTarget(ImageView view) {
      this(view, GlideDrawable.LOOP_FOREVER);
  }

  public GlideDrawableImageViewTarget(ImageView view, int maxLoopCount) {
      super(view);
      this.maxLoopCount = maxLoopCount;
  }

  @Override
  public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
      if (!resource.isAnimated()) {
          float viewRatio = view.getWidth() / (float) view.getHeight();
          float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
          if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN
                  && Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
              resource = new SquaringDrawable(resource, view.getWidth());
          }
      }
      super.onResourceReady(resource, animation);
      this.resource = resource;
      resource.setLoopCount(maxLoopCount);
      resource.start();
  }

  @Override
  protected void setResource(GlideDrawable resource) {
      view.setImageDrawable(resource);
  }

  @Override
  public void onStart() {
      if (resource != null) {
          resource.start();
      }
  }

  @Override
  public void onStop() {
      if (resource != null) {
          resource.stop();
      }
  }
}

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

  ...

  @Override
  public void onResourceReady(Z resource, GlideAnimation<? super Z> glideAnimation) {
      if (glideAnimation == null || !glideAnimation.animate(resource, this)) {
          setResource(resource);
      }
  }

  protected abstract void setResource(Z resource);

}


假设这是我们的 APP 第一次使用 Glide 加载一张图片,那么流程如下:


image.png

基本用法:

依赖:implementation 'com.github.bumptech.glide:glide:4.11.0'
Glide.with(getApplicationContext())
              .load(path) //加载图片,可以是链接,可以是本地图片、二进制
              .placeholder(R.mipmap.ic_launcher)//加载完成之前显示的图片
              .error(R.drawable.error) //加载失败图片
              .apply(new RequestOptions().override(36,36).centerCrop())
              .skipMemoryCache(true)
              .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
              .priority(Priority.HIGH) //优先级
              .into(imageView);

Bitmap大小计算:

一个BitMap位图占用的内存=图片长度*图片宽度*单位像素占用的字节数

单位像素一个字节:
ALPHA_8:一个像素占用1个字节

单位像素二个字节的:
ARGB_4444:一个像素占用2个字节。
RGB_565:一个像素占用2个字节。

单位像素四个字节的:
ARGB_8888:一个像素占用4个字节。

如果大图的尺寸大于我们要显示的区域,则先把大图比例/显示区域对大图进行压缩:

public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId, int reqWidth, int reqHeight) {
      final BitmapFactory.Options options = new BitmapFactory.Options();
      options.inJustDecodeBounds = true;
      BitmapFactory.decodeResource(res, resId, options);
      options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
      options.inJustDecodeBounds = false;
      return BitmapFactory.decodeResource(res, resId, options);
  }

  public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
      // Raw height and width of image
      final int height = options.outHeight;   final int width = options.outWidth;
      int inSampleSize = 1;
      if (height > reqHeight || width > reqWidth) {
          // Calculate ratios of height and width to requested height and width,计算出实际宽高和目标宽高的比率
          final int heightRatio = Math.round((float) height / (float) reqHeight);
          // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高一定都会大于等于目标的宽和高。
          final int widthRatio = Math.round((float) width / (float) reqWidth);
          inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
          // Anything more than 2x the requested pixels we'll sample down
          final float totalPixels = width * height;
          // further
          final float totalReqPixelsCap = reqWidth * reqHeight * 2;
          while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
              inSampleSize++;
          }
      }   return inSampleSize;
  }
上一篇 下一篇

猜你喜欢

热点阅读