Glide图片下载架构完全解析


本文将分析图片处理框架Glide的加载流程,同时也会对缓存,网络请求,自定义模块做相应分析,文中代码使用的是目前(2020.3)最新的版本4.11.0。

Glide框架总览

Glide是一个非常复杂的框架,下面我们根据各模块的作用做出如下划分:
Glide主要模块

图片加载源码分析

Glide最基本的使用流程就是下面这行代码,其它所有扩展的额外功能都是以其建造者链式调用的基础上增加的。

GlideApp.with(context).load(url).into(imageView);

下面我们将对该用法进行深入的源码分析。

Glide.with()

Glide为我们提供多个Glide.with()实现,我们主要围绕with(Context context) 展开分析
with方法

1. Glide.with(Context)
return getRetriever(activity).get(activity)
@Glide.java
RequestManagerRetriever getRetriever(context) {
	...
	return Glide.get(context).getRequestManagerRetriever();
}
//使用双检锁方式实现单例
public static Glide get(@NonNull Context context) {
	if (glide == null) {
	 //获取用户自定义GlideModule
	  GeneratedAppGlideModule annotationGeneratedModule =getAnnotationGeneratedGlideModules(context.getApplicationContext());
	  synchronized (Glide.class) {
		if (glide == null) {
		  checkAndInitializeGlide(context, annotationGeneratedModule);
		}
	  }
	}
	return glide;
}
void checkAndInitializeGlide(context, generatedAppGlideModule) {
	...
	initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
	...
}
void initializeGlide(context, builder, annotationGeneratedModule) {
	...
	//1.1 获取manifest中GlideModule模块
	if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();
    }
	...
	//将自定义GlideModule信息(factory)添加到GlideBuilder中
	RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory : null;
    builder.setRequestManagerFactory(factory);
    //1.2将GlideBuilder通过applyOptions添加到GlideModule中
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
	//--> 2.创建Glide实例
	Glide glide = builder.build(applicationContext);
	...
	//1.3 registerComponents:用于注册编解码器,ModelLoader等,具体可以参考@Resistry中的方法
	if (annotationGeneratedModule != null) {
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
}

这里使用双检锁模式来获取Glide对象的单例,在1.1中,如果没有带注解的GlideModule,或者该GlideModule中isManifestParsingEnabled()为true,则调用ManifestParser解析AndroidManifest.xml中以获取值为“GlideModule”的meta-data配置,并将相应的自定义模块实例化。由于可以实例化多个GlideModule,因此得到的是一个GlideModule的List集合。
在1.2中,将builder通过applyOptions方法加入到module中,在自定义module中我们通过重写applyOptions方法可以对module进行定制。
在1.3中,提供registerComponents来修改glide中组件,用于注册编解码器,ModelLoader等,比如替换网络请求成OkHttp的方法, 就是通过该函数注册

2. GlideBuilder.build

GlideBuilder 是用来创建 Glide 实例的类,具体实现如下:

@NonNull
  Glide build(@NonNull Context context) {
    if (sourceExecutor == null) { //创建图片线程池
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }
    if (diskCacheExecutor == null) { //创建硬盘缓存线程池
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }
    if (animationExecutor == null) { //创建动画线程池
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }
    //TODO:默认4M,如果是低内存设备为2M,后文[缓存机制]会有详细分析
    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(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }
    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }
    //创建requestManagerRetriever,用于创建requestManager
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled,
        isImageDecoderEnabledForBitmaps);
  }

这个方法中会创建BitmapPool、MemoryCache、DiskCache等对象的实例,并在最后一句创建一个Glide对象的实例,然后将前面创建的这些实例传入到Glide对象当中,以供后续的图片加载操作使用。
同时,我们注意到,build 中创建任何对象都有一个判空的检查,只有对象为空才会去创建其实例,也就是说,我们可以applyOptions方法对这些配置对象提前初始化,进而实现更改Glide配置的功能。
具体如何自定义模块,可以参考郭神的文章:《Android图片加载框架最全解析(六),探究Glide的自定义模块功能》,文中涉及如何替换网络组件,如何替换缓存模块等非常棒的操作。

3. Glide构造方法

将任务管理对象(registry)、array缓存、管理引擎等传入glideContext

 Glide(...) {
	...
	//登记任务管理对象,根据任务类型,分发给相应任务进行处理
    registry = new Registry();
    ...
	//注册编解码器,ModelLoader等组件
    registry
        .append(ByteBuffer.class, new ByteBufferEncoder())
        .append(InputStream.class, new StreamEncoder(arrayPool))
     ...
	 //Target工厂: 根据子类生产对应类型taget,
	 //包括BitmapImageViewTarget和DrawableImageViewTarget
    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    glideContext =
        new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptionsFactory,
            defaultTransitionOptions,
            defaultRequestListeners,
            engine,
            isLoggingRequestOriginsEnabled,
            logLevel);
  }
4. RequestManagerRetriever.get
  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)) {
	  //如果非ApplicationContext, 将请求的生命周期同对于的Fragment/Activity绑定
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        return get((Activity) context);
      } else if (context instanceof ContextWrapper
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
	//如果是ApplicationContext或者子线程,和Application生命周期绑定
    return getApplicationManager(context);
  }
  @NonNull
  private RequestManager supportFragmentGet(...) {
    //创建一个不可见的Fragment,用于检测Activity生命周期
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) { //确保一个Activity对于一个requestManager
      Glide glide = Glide.get(context);
      //创建requestManger,将Glide和Activity生命周期绑定
      //参考[5.requestManager生命周期]
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), 
          current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

通过RequestManagerRetriever.get创建RequestManager,详细逻辑如下:

  1. 如果 with 方法的参数为 Activity 或者 Fragment ,则最终调用 RequestManagerRetriever 中的 fragmentGet(Context, android.app.FragmentManager) 方法创建 RequestManager
  2. 如果 with 方法的参数为 android.support.v4.app.Fragment 或者android.support.v4.app.FragmentActivity,则最终调用 supportFragmentGet(Context, android.support.v4.app.FragmentManager) 方法创建 RequestManager
  3. 如果 with 方法的参数为 Context,则会判断其来源是否属于 FragmentActivityActivity,则按照上面的逻辑进行处理,否则最终调用 getApplicationManager(Context) 方法创建 RequestManager
  4. 如果在子线程或者系统版本小于17,则调用getApplicationManager(Context) 方法创建 RequestManager
    同时,由supportFragmentGet可知,一个Activity对应一个RequestManager。
5. RequestManager生命周期

通过RequestManagerRetriever.get创建requestManager,通过requestManagerActivityGlide生命周期绑定。

 //RequestManager构造函数
 RequestManager(...) {
    //在主线程绑定Glide和Activity的生命周期
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);
    defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
    glide.registerRequestManager(this);
 }
  
private final Runnable addSelfToLifecycle =
  new Runnable() {
	@Override
	public void run() {
	  //切换到主线程
	  lifecycle.addListener(RequestManager.this);
	}
  };
  
 //RequestManager中LifecycleLister实现
 public class RequestManager
    implements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> {
	...
	//开始暂停的请求
	public void onStart() {
		resumeRequests();
	}
	//停止所有的请求
	@Override
	public void onStop() {
		pauseRequests();
	}
	//关闭所以的请求
	@Override
	public void onDestroy() {
		requestTracker.clearRequests();
	}
	...
}

通过上面 RequestManagerRetrieverResquestManager 的介绍,我们知道创建 RequestManager 时需要一个 FragmentManager 参数(全局 RequestManager 除外),那么再创建 RequestManager 时会先创建一个不可见的 RequestManagerFragment ,通过 FragmentMamager加入到当前页面,用这个不可见的 Fragment 即可检测页面的生命周期,进而将Glide和页面生命周期绑定。

6. Registry

Registry(com.bumptech.glide.Registry)是用来注册管理任务执行对象的管理类,可以简单理解为:Registry是一个工厂,而其中所有注册的对象都是一个工厂员工,当任务分发时,根据当前任务的性质,分发给相应员工进行处理。该类可细分为:ModelLoaderRegistryEncoderRegistryResourceDecoderRegistryResourceEncoderRegistryDataRewinderRegistryTranscoderRegistryImageHeaderParserRegistry共七种。Registry通过各个细分的管理类通过HashMap或者List来管理执行类及其执行方法的对应关系。

public class Registry {
  @NonNull
  @SuppressWarnings("unchecked")
  public <X> Encoder<X> getSourceEncoder(@NonNull X data) throws 		NoSourceEncoderAvailableException {
      //根据data通过encoderRegistry来获取对于的encoder
    Encoder<X> encoder = encoderRegistry.getEncoder((Class<X>) data.getClass());
    if (encoder != null) {
      return encoder;
    }
    throw new NoSourceEncoderAvailableException(data.getClass());
  } 
    
  @NonNull
  public <Data> Registry append(@NonNull Class<Data> dataClass, @NonNull Encoder<Data> encoder) {
     //保存dataClass和encoder对应关系到encoderRegistry工厂
    encoderRegistry.append(dataClass, encoder);
    return this;
  }
} 
public class EncoderRegistry {
      private final List<Entry<?>> encoders = new ArrayList<>();
    
     @Nullable
  public synchronized <T> Encoder<T> getEncoder(@NonNull Class<T> dataClass) {
    for (Entry<?> entry : encoders) {
      if (entry.handles(dataClass)) {
        return (Encoder<T>) entry.encoder;
      }
    }
    return null;
  }
}
7. Glide.with小结

根据上面分析,汇总成下面流程图:
Glide流程
从图上可以看到,Glide.with主要完成:

  1. 各类初始化,主要包括:线程池、缓存、EnginerequestManagerregisterglideContext
  2. 创建透明Fragment, 将Glide和视图生命周期进行绑定。
load(url)
1.RequestManager.load
public RequestBuilder<Drawable> load(@Nullable Bitmap bitmap) {
    return asDrawable().load(bitmap);
  }
2.asDrawable()
@RequestManager.java
public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
}
//最终返回了一个RequestBuilder
public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
}
protected RequestBuilder(...) {
    this.glide = glide;
    this.requestManager = requestManager;
    this.transcodeClass = transcodeClass;
    this.context = context;
    this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
    this.glideContext = glide.getGlideContext();
    //初始化请求回调
    initRequestListeners(requestManager.getDefaultRequestListeners());
    apply(requestManager.getDefaultRequestOptions());
  }
3.load(string)
@RequestBuilder.java
public RequestBuilder<TranscodeType> load(@Nullable String string) {
    return loadGeneric(string);
}
//将url赋值给RequestBuilder.model
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }

可以看到,load主要是创建RequestBuilder并设置请求的URL(model),并记录了URL已设置的状态。
到此,我们可以总结出 RequestManager 两个主要作用:

  1. 创建 RequestBuilder,用于保存请求URL和初始化请求回调;
  2. 通过绑定页面生命周期来管理请求的启动结束等
into(target)
1.RequestBuilder.into
@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
	Util.assertMainThread();
	Preconditions.checkNotNull(view);
	BaseRequestOptions<?> requestOptions = this;
	//ImageView默认ScaleType为FIT_CENTER,Glide可以通过dontTransform()或者transform(...)来关闭或使用图片变化
	if (!this.isTransformationSet() && this.isTransformationAllowed() && view.getScaleType() != null) {
		switch(view.getScaleType()) {
		case CENTER_CROP:
			requestOptions = this.clone().optionalCenterCrop();
			break;
		case CENTER_INSIDE:
			requestOptions = this.clone().optionalCenterInside();
			break;
		case FIT_CENTER: 
		case FIT_START:
		case FIT_END:
			requestOptions = this.clone().optionalFitCenter();
			break;
		case FIT_XY:
			requestOptions = this.clone().optionalCenterInside();
		case CENTER:
		case MATRIX:
		}
	}
	
    //根据transcodeClass生成对应的ViewTarget,并指定RequestBuilder.into回调主线程执行
	return (ViewTarget)this.into(this.glideContext.buildImageViewTarget(view, this.transcodeClass), (RequestListener)null, (BaseRequestOptions)requestOptions, Executors.mainThreadExecutor());
}
2.GlideContext.buildImageViewTarget
return this.imageViewTargetFactory.buildTarget(imageView, transcodeClass);
3. ImageViewTargetFactory.buidTarget
@NonNull
public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view, @NonNull Class<Z> clazz) {
	if (Bitmap.class.equals(clazz)) {
		return new BitmapImageViewTarget(view);
	} else if (Drawable.class.isAssignableFrom(clazz)) {
		return new DrawableImageViewTarget(view);
	} else {
		throw new IllegalArgumentException("Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
	}
}

根据这段代码可知,glideContext.buildImageViewTarget 通过传入class类型不同,分别生成不同的ImageVieTarget,传入Bitmap则生成BitmapImageViewTarget, 传入Drawable则生成DrawableImageViewTarget

4. RequestBuilder.into
private <Y extends Target<TranscodeType>> Y into(@NonNull Y target, @Nullable RequestListener<TranscodeType> targetListener, BaseRequestOptions<?> options, Executor callbackExecutor) {
	Preconditions.checkNotNull(target);
	if (!this.isModelSet) {
		throw new IllegalArgumentException("You must call #load() before calling #into()");
	} else {
		// -->1. 建立请求
		Request request = this.buildRequest(target, targetListener, options, callbackExecutor);
		Request previous = target.getRequest();
		if (request.isEquivalentTo(previous) && !this.isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
			if (!((Request)Preconditions.checkNotNull(previous)).isRunning()) {
				previous.begin();
			}
			return target;
		} else {
			this.requestManager.clear(target);
			target.setRequest(request);
             // -->2. 请求追踪
			this.requestManager.track(target, request);
			return target;
		}
	}
}

RequestBuilder.into的实现主要是buildRequest建立请求和requestManager.track请求追踪,下面我们将重点分析这两部分。
buildRequest

// 1. 建立请求
private Request buildRequest(Target<TranscodeType> target, @Nullable RequestListener<TranscodeType> targetListener, BaseRequestOptions<?> requestOptions, Executor callbackExecutor) {
	// -->1.1 通过递归调用创建请求
	return this.buildRequestRecursive(new Object(), target, targetListener, (RequestCoordinator)null, this.transitionOptions, requestOptions.getPriority(), requestOptions.getOverrideWidth(), requestOptions.getOverrideHeight(), requestOptions, callbackExecutor);
}
// 1.1 通过递归调用创建请求
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是否需要带error
	ErrorRequestCoordinator errorRequestCoordinator = null;
	if (this.errorBuilder != null) {
		//errorBuilder不为空,此处为[标记1]递归调用
		errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, (RequestCoordinator)parentCoordinator);
		parentCoordinator = errorRequestCoordinator;
	}
	// --> 1.2 创建带缩略图的请求
	Request mainRequest = this.buildThumbnailRequestRecursive(requestLock, target, targetListener, (RequestCoordinator)parentCoordinator, transitionOptions, priority, overrideWidth, overrideHeight, requestOptions, callbackExecutor);
	if (errorRequestCoordinator == null) {
		//不带error直接返回mainRequest
		return mainRequest;
	} else {
		int errorOverrideWidth = this.errorBuilder.getOverrideWidth();
		int errorOverrideHeight = this.errorBuilder.getOverrideHeight();
		if (Util.isValidDimensions(overrideWidth, overrideHeight) && !this.errorBuilder.isValidOverride()) {
			errorOverrideWidth = requestOptions.getOverrideWidth();
			errorOverrideHeight = requestOptions.getOverrideHeight();
		}
		// [标记1] 回调当前方法,构建带error的请求
		Request errorRequest = this.errorBuilder.buildRequestRecursive(requestLock, target, targetListener, errorRequestCoordinator, this.errorBuilder.transitionOptions, this.errorBuilder.getPriority(), errorOverrideWidth, errorOverrideHeight, this.errorBuilder, callbackExecutor);
		errorRequestCoordinator.setRequests(mainRequest, errorRequest);
		return errorRequestCoordinator;
	}
}
// 1.2 创建带缩略图的请求
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 (this.thumbnailBuilder != null) { //thumbnailBuilder不不为空
		if (this.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()");
		} else {
			// 获取缩略图配置
			TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions = this.thumbnailBuilder.transitionOptions;
			if (this.thumbnailBuilder.isDefaultTransitionOptionsSet) {
				thumbTransitionOptions = transitionOptions;
			}
			Priority thumbPriority = this.thumbnailBuilder.isPrioritySet() ? this.thumbnailBuilder.getPriority() : this.getThumbnailPriority(priority);
			int thumbOverrideWidth = this.thumbnailBuilder.getOverrideWidth();
			int thumbOverrideHeight = this.thumbnailBuilder.getOverrideHeight();
			if (Util.isValidDimensions(overrideWidth, overrideHeight) && !this.thumbnailBuilder.isValidOverride()) {
				thumbOverrideWidth = requestOptions.getOverrideWidth();
				thumbOverrideHeight = requestOptions.getOverrideHeight();
			}
			
			// 创建ThumbnailRequestCoordinator对象
			ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(requestLock, parentCoordinator);
			// 创建原图片请求对象
			Request fullRequest = this.obtainRequest(requestLock, target, targetListener, requestOptions, coordinator, transitionOptions, priority, overrideWidth, overrideHeight, callbackExecutor);
			this.isThumbnailBuilt = true;
			// 用递归方式创建缩略图请求
			Request thumbRequest = this.thumbnailBuilder.buildRequestRecursive(requestLock, target, targetListener, coordinator, thumbTransitionOptions, thumbPriority, thumbOverrideWidth, thumbOverrideHeight, this.thumbnailBuilder, callbackExecutor);
			this.isThumbnailBuilt = false;
			// 将原图片请求和缩略图请求打包到ThumbnailRequestCoordinator中
			coordinator.setRequests(fullRequest, thumbRequest);
			return coordinator;
		}
	} else if (this.thumbSizeMultiplier != null) {  /缩略图缩放比例不为空
		ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(requestLock, parentCoordinator);
		Request fullRequest = this.obtainRequest(requestLock, target, targetListener, requestOptions, coordinator, transitionOptions, priority, overrideWidth, overrideHeight, callbackExecutor);
		BaseRequestOptions<?> thumbnailOptions = requestOptions.clone().sizeMultiplier(this.thumbSizeMultiplier);
		Request thumbnailRequest = this.obtainRequest(requestLock, target, targetListener, thumbnailOptions, coordinator, transitionOptions, this.getThumbnailPriority(priority), overrideWidth, overrideHeight, callbackExecutor);
		coordinator.setRequests(fullRequest, thumbnailRequest);
		return coordinator;
	} else { //没有缩略图,直接返回原图片请求,通过obtainRequest最终返回一个SingleRequest对象
		return this.obtainRequest(requestLock, target, targetListener, requestOptions, parentCoordinator, transitionOptions, priority, overrideWidth, overrideHeight, callbackExecutor);
	}
}

代码中fullRequest表示原始的请求,thumbRequest表示缩略图请求,mainRequest表示打包了fullRequest和thumbRequest得请求,errorRequest错误重试请求;具体流程参考下面流程图,可以方便理解:
request创建流程图
上面我们提到,最终得到得是一个SingleRequest得对象,SingleRequest以来关系如下:

public final class SingleRequest<R> implements Request, SizeReadyCallback, ResourceCallback
public interface Request {
    void begin();
	.......
}
public interface SizeReadyCallback {
    void onSizeReady(int var1, int var2);
}
public interface ResourceCallback {
    void onResourceReady(Resource<?> var1, DataSource var2);
    ......
}

onSizeReady()和begin()是SingleRequest最重要得两个实现方法,相关方法得调用在requestTracker种,下面我们将分析RequstBuilder得第二个重点requestManager.track

5.requestManager.track
// 2.追踪Request
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    // -->2.1 将target保存到targetTracker中
    this.targetTracker.track(target);
    // -->2.2 运行请求
    this.requestTracker.runRequest(request);
}
// 2.1 @TargetTracker.java
private final Set<Target<?>> targets = Collections.newSetFromMap(new WeakHashMap());
public void track(@NonNull Target<?> target) {
 	将tartget加入set中
    this.targets.add(target);
}
// 2.2 @RequestTracker.java
private final Set<Request> requests = Collections.newSetFromMap(new WeakHashMap());
private final List<Request> pendingRequests = new ArrayList();
public void runRequest(@NonNull Request request) {
    this.requests.add(request);
    if (!this.isPaused) {
        // -->2.3调用SingleRequest.begin()方法开始请求
        request.begin();
    } else {
        request.clear();
        if (Log.isLoggable("RequestTracker", 2)) {
            Log.v("RequestTracker", "Paused, delaying request");
        }
        //如果是暂停状态,将请求加入pending队列中
        this.pendingRequests.add(request);
    }
}
// 2.3 开始请求 @SingleRequest.java
public void begin() {
    synchronized(this.requestLock) {
       ......
            if (Util.isValidDimensions(this.overrideWidth, this.overrideHeight)) {
                // -->2.4 请求开始
                this.onSizeReady(this.overrideWidth, this.overrideHeight);
            } else {
                // -->2.5 如果没有override()方法设置固定宽高,根据imageView宽高计算图片宽高
                this.target.getSize(this);
            }
	  ......
    }
}
// 2.4 @SingleRequest
public void onSizeReady(int width, int height) {
    ......
	// -->2.6 通过引擎加载, 倒数第二个参数,传入回调,会砸4.7中用到
            this.loadStatus = this.engine.load(this.glideContext, this.model, this.requestOptions.getSignature(), this.width, this.height, this.requestOptions.getResourceClass(), this.transcodeClass, this.priority, this.requestOptions.getDiskCacheStrategy(), this.requestOptions.getTransformations(), this.requestOptions.isTransformationRequired(), this.requestOptions.isScaleOnlyOrNoTransform(), this.requestOptions.getOptions(), this.requestOptions.isMemoryCacheable(), this.requestOptions.getUseUnlimitedSourceGeneratorsPool(), this.requestOptions.getUseAnimationPool(), this.requestOptions.getOnlyRetrieveFromCache(), this, this.callbackExecutor);
    ......
}
// 2.5 计算图片宽高 @ViewTarget.java
void getSize(@NonNull SizeReadyCallback cb) {
    ......
        //计算完图片宽高,最终回调2.4SingleRequest.onSizeReady方法
        cb.onSizeReady(currentWidth, currentHeight);
    ......
}
// 2.6 通过引擎加载 @Engine.java
public <R> Engine.LoadStatus load(...) {
    synchronized(this) {
        // -->2.7 加载缓存
        memoryResource = this.loadFromMemory(key, isMemoryCacheable, startTime);
        if (memoryResource == null) {
            // -->2.8 没缓存,加载网络资源
            return this.waitForExistingOrStartNewJob(...);
        }
    }
    // 回到到singleRequest类中
    cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
    return null;
}
// 2.7 加载缓存 @Engine.java
@Nullable
private EngineResource<?> loadFromMemory(EngineKey key, boolean isMemoryCacheable, long startTime) {
    if (!isMemoryCacheable) {
        // 如果设置为不使用缓存,直接返回
        return null;
    } else {
        // 首先,在弱引用缓存map中查找,找到就直接返回active
        EngineResource<?> active = this.loadFromActiveResources(key);
        if (active != null) {
            if (VERBOSE_IS_LOGGABLE) {
                logWithTimeAndKey("Loaded resource from active resources", startTime, key);
            }
            return active;
        } else {
            // 接着在内存memoryCache中寻找,找到就直接返回cache
            // memoryCache在GlideBuilder.build中初始化,为LruResourceCache上文有相关代码
            EngineResource<?> cached = this.loadFromCache(key);
            if (cached != null) {
                if (VERBOSE_IS_LOGGABLE) {
                    logWithTimeAndKey("Loaded resource from cache", startTime, key);
                }
                return cached;
            } else {
                return null;
            }
        }
    }
}
//2.8 没缓存,加载网络资源 @Engine.java
private <R> Engine.LoadStatus waitForExistingOrStartNewJob(...) {
    EngineJob<?> current = this.jobs.get(key, onlyRetrieveFromCache);
    if (current != null) {
        current.addCallback(cb, callbackExecutor);
        if (VERBOSE_IS_LOGGABLE) {
            logWithTimeAndKey("Added to existing load", startTime, key);
        }
        return new Engine.LoadStatus(cb, current);
    } else {
        // 创建下载工程任务类
        EngineJob<R> engineJob = this.engineJobFactory.build(key, isMemoryCacheable, useUnlimitedSourceExecutorPool, useAnimationPool, onlyRetrieveFromCache);
         // 创建解析工作对象
        DecodeJob<R> decodeJob = this.decodeJobFactory.build(glideContext, model, key, signature, width, height, resourceClass, transcodeClass, priority, diskCacheStrategy, transformations, isTransformationRequired, isScaleOnlyOrNoTransform, onlyRetrieveFromCache, options, engineJob);
        // 存入Jobs内部维护的HashMap中
        this.jobs.put(key, engineJob);
        engineJob.addCallback(cb, callbackExecutor);
        // -->2.9 启动请求线程
        engineJob.start(decodeJob);
        if (VERBOSE_IS_LOGGABLE) {
            logWithTimeAndKey("Started new load", startTime, key);
        }
        return new Engine.LoadStatus(cb, engineJob);
    }
}
// 2.9 启动请求线程, 根据配置不同,使用不同的解码线程池 @Engine.java
public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor = decodeJob.willDecodeFromCache() ? this.diskCacheExecutor : this.getActiveSourceExecutor();
    // -->2.10 启动解码任务
    executor.execute(decodeJob);
}
// 2.10 启动解码任务  @DecodeJob.java
public void run() {
	......
    try {
        if (!this.isCancelled) {
            // -->2.11 运行解码任务
            this.runWrapped();
            return;
        }
    ......
}
//2.11 运行解码任务 @DecodeJob.java
private void runWrapped() {
    switch(this.runReason) {
        case INITIALIZE: 
            // -->2.12 根据缓存策略生成对应stage,stage的推进就代表缓存的查找顺序
            this.stage = this.getNextStage(DecodeJob.Stage.INITIALIZE);
            // -->2.13 根据stage生成Generator
            this.currentGenerator = this.getNextGenerator();
            // -->2.14 执行Generator的startNext()方法
            this.runGenerators();
            break;
        case SWITCH_TO_SOURCE_SERVICE:
            this.runGenerators();
            break;
        case DECODE_DATA:
            this.decodeFromRetrievedData();
            break;
        default:
            throw new IllegalStateException("Unrecognized run reason: " + this.runReason);
    }
}
    
//2.12 根据缓存策略生成对应stage  @DecodeJob.java
private DecodeJob.Stage getNextStage(DecodeJob.Stage current) {
    switch(current) {
        case RESOURCE_CACHE: //如果支持原图尺寸,下一个state就是DATA_CACHE,否则,从DATA_CACHE开始往下判断
            return this.diskCacheStrategy.decodeCachedData() ? DecodeJob.Stage.DATA_CACHE : this.getNextStage(DecodeJob.Stage.DATA_CACHE);
        case DATA_CACHE: //如果只读缓存,下一个Stage为FINISHED,否则就是SOURCE
            return this.onlyRetrieveFromCache ? DecodeJob.Stage.FINISHED : DecodeJob.Stage.SOURCE;
        case SOURCE:
        case FINISHED:
            return DecodeJob.Stage.FINISHED;
        case INITIALIZE: //如果支持多尺寸,下一个state就是RESOURCE_CACHE,否则,从RESOURCE_CACHE开始往下判断
            return this.diskCacheStrategy.decodeCachedResource() ? DecodeJob.Stage.RESOURCE_CACHE : this.getNextStage(DecodeJob.Stage.RESOURCE_CACHE);
        default:
            throw new IllegalArgumentException("Unrecognized stage: " + current);
    }
}
    
// 2.13 根据stage获取Generator  @DecodeJob.java
private DataFetcherGenerator getNextGenerator() {
    switch(this.stage) {
        case RESOURCE_CACHE: //缓存多尺寸
            return new ResourceCacheGenerator(this.decodeHelper, this);
        case DATA_CACHE:  //缓存原图
            return new DataCacheGenerator(this.decodeHelper, this);
        case SOURCE: //下载远程图片
            return new SourceGenerator(this.decodeHelper, this);
        case FINISHED:
            return null;
        default:
            throw new IllegalStateException("Unrecognized stage: " + this.stage);
    }
}
    
//2.14 循环执行Generators的startNext()方法 @DecodeJob.java
private void runGenerators() {
	......
    while(!this.isCancelled && this.currentGenerator != null && !(isStarted = this.currentGenerator.startNext())) { //--> 2.15 执行Generator的startNext()方法
        //获取下一个stage
        this.stage = this.getNextStage(this.stage);
        //获取下一个Generator
        this.currentGenerator = this.getNextGenerator();
        if (this.stage == DecodeJob.Stage.SOURCE) {
            this.reschedule();
            return;
        }
    }
    ......
}
 
 // 2.15 以SourceGenerator为例,@SourceGenerator
 public boolean startNext() {
     ......
     boolean started = false;
     while(!started && this.hasNextModelLoader()) {
         this.loadData = (LoadData)this.helper.getLoadData().get(this.loadDataListIndex++);
         // 根据缓存策略来筛选loaddata,这里最终获取的loaddata是HttpGlideUrlLoader,Fetcher是HttpUrlFetcher
         if (this.loadData != null && (this.helper.getDiskCacheStrategy().isDataCacheable(this.loadData.fetcher.getDataSource()) || this.helper.hasLoadPath(this.loadData.fetcher.getDataClass()))) {
             started = true;
              // -->2.16 加载数据 
             this.startNextLoad(this.loadData);
         }
     }
     return started;
 }
    
 // 2.16 加载数据 @SourceGenerator.java
 private void startNextLoad(final LoadData<?> toStart) {
     	// -->2.17通过loadData方法获取图片数据
        this.loadData.fetcher.loadData(this.helper.getPriority(), new DataCallback<Object>() {this.helper.getPriority(), new DataCallback<Object>() {
            public void onDataReady(@Nullable Object data) {
                if (SourceGenerator.this.isCurrentRequest(toStart)) {
                    // -->3.1 获取数据之后回调数据到SourceGenerator进行解码
                    SourceGenerator.this.onDataReadyInternal(toStart, data);
                }
            }
            ......
        }
 }
// 2.17 获取图片数据 @HttpUrlFetcher.java
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
	......
    try {
        // -->2.18 网络下载图片
        InputStream result = this.loadDataWithRedirects(this.glideUrl.toURL(), 0, (URL)null, this.glideUrl.getHeaders());
        callback.onDataReady(result);
    } catch (IOException var9) {...}
	......
}
       
// 2.18 使用HttpURLConnection下载网络图片 @HttpUrlFetcher.java
private InputStream loadDataWithRedirects(...) throws IOException {
    if (redirects >= 5) {
        //设置最大重定向次数为5次
        throw new HttpException("Too many (> 5) redirects!");
    } else {
        ......
        this.urlConnection.setConnectTimeout(this.timeout);
        this.urlConnection.setReadTimeout(this.timeout);
        this.urlConnection.setUseCaches(false);
        this.urlConnection.setDoInput(true);
        this.urlConnection.setInstanceFollowRedirects(false);
        this.urlConnection.connect();
        this.stream = this.urlConnection.getInputStream();
        if (this.isCancelled) {
            return null;
        } else {
            int statusCode = this.urlConnection.getResponseCode();
            if (isHttpOk(statusCode)) {
                // -->2.19请求成功,获取图片数据
                return this.getStreamForSuccessfulRequest(this.urlConnection);
            } else if (isHttpRedirect(statusCode)) {
                	......
                    // 重定向次数加1
                    return this.loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
                }
            } else if (statusCode == -1) {
                throw new HttpException(statusCode);
            } else {
                throw new HttpException(this.urlConnection.getResponseMessage(), statusCode);
            }
        }
    }
}
                                       
// 2.19 获取数据流 @HttpUrlFetcher.java
private InputStream getStreamForSuccessfulRequest(HttpURLConnection urlConnection) throws IOException {
    if (TextUtils.isEmpty(urlConnection.getContentEncoding())) {
        int contentLength = urlConnection.getContentLength();
        this.stream = ContentLengthInputStream.obtain(urlConnection.getInputStream(), (long)contentLength);
    } else {
        if (Log.isLoggable("HttpUrlFetcher", 3)) {
            Log.d("HttpUrlFetcher", "Got non empty content encoding: " + urlConnection.getContentEncoding());
        }
        // 获取数据流
        this.stream = urlConnection.getInputStream();
    }
    return this.stream;
}                            

终于到了图篇下载的地方,我们最后获取的是数据流,接下来的步骤是数据流解码。

6.返回数据流解码
// -->3.1 返回数据流到SourceGenerator @SourceGenerator.java
void onDataReadyInternal(LoadData<?> loadData, Object data) {
    DiskCacheStrategy diskCacheStrategy = this.helper.getDiskCacheStrategy();
    if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
        this.dataToCache = data;
        this.cb.reschedule();
    } else {
        // --> 3.2 回到DecodeJob继续处理,会调用到decodeFromRetrievedData处理
        this.cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher, loadData.fetcher.getDataSource(), this.originalKey);
    }
}
// 3.2 处理返回数据 @DecodeJob.java
 private void decodeFromRetrievedData() {
     ......
     try {
         // -->3.3 在decodeFromFetcher中调用decodeFromFetcher处理,从数据中解码得到资源
         resource = this.decodeFromData(this.currentFetcher, this.currentData, this.currentDataSource);
     } catch (GlideException var3) {
         var3.setLoggingDetails(this.currentAttemptingKey, this.currentDataSource);
         this.throwables.add(var3);
     }
	
     if (resource != null) {
         // -->4.1 编码和发布资源
         this.notifyEncodeAndRelease(resource, this.currentDataSource);
     } else {
         this.runGenerators();
     }
 }
// 3.3 @DecodeJob.java
 private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource) throws GlideException {
        LoadPath<Data, ?, R> path = this.decodeHelper.getLoadPath(data.getClass());
     	// -->3.4 将解码任务分发给LoadPath
        return this.runLoadPath(data, dataSource, path);
}
// 3.4 将解码任务分发给LoadPath
private <Data, ResourceType> Resource<R> runLoadPath(...) throws GlideException {
    Options options = this.getOptionsWithHardwareConfig(dataSource);
    // 将数据打包到Rewinder对象中,根据data的类型获取对应的rewinder,这里为ByteBufferRewinder
    DataRewinder rewinder = this.glideContext.getRegistry().getRewinder(data);
    Resource var6;
    try {
        // -->3.5 LoadPath.load -> LoadPath.loadWithExceptionList -> DecodePath.decodeResource ->
        // DecodePath.decodeResourceWithList
        var6 = path.load(rewinder, options, this.width, this.height, new DecodeJob.DecodeCallback(dataSource));
    } finally {
        rewinder.cleanup();
    }
    return var6;
}
// 3.5 @DecodePath.java
private Resource<ResourceType> decodeResourceWithList(...) throws GlideException {
	......
        try {
            DataType data = rewinder.rewindAndGet();
            if (decoder.handles(data, options)) {
                data = rewinder.rewindAndGet();
                // -->3.6根据dataType使用对应的decoder,这里decoder是ByteBufferBitmapDecoder
                result = decoder.decode(data, width, height, options);
            }
        }
    ......
        if (result == null) {
            // 如果找不到合适的decoder抛出异常,回到LoadPath.loadWithExceptionList中用下一个DecodePath处理
            throw new GlideException(this.failureMessage, new ArrayList(exceptions));
        } else {
            return result;
        }
}
// 3.6 对数据进行处理 @ByteBufferBitmapDecoder.java
public Resource<Bitmap> decode(...) throws IOException {
    InputStream is = ByteBufferUtil.toStream(source);
    // -->3.7 使用downsampler对流数据进行解码和图像处理等,并封装为Resource<Bitmap>对象返回
    return this.downsampler.decode(is, width, height, options);
}
// 3.7 使用downsampler对流数据进行解码和图像处理等 @Downsampler.java
private Resource<Bitmap> decode(...) throws IOException {
    BitmapResource var14;
    try {
        //Bitmap处理
        Bitmap result = this.decodeFromWrappedStreams(imageReader, bitmapFactoryOptions, downsampleStrategy, decodeFormat, preferredColorSpace, isHardwareConfigAllowed, requestedWidth, requestedHeight, fixBitmapToRequestedDimensions, callbacks);
        //打包为Resource<Bitmap>对象返回
        var14 = BitmapResource.obtain(result, this.bitmapPool);
    } finally {
        releaseOptions(bitmapFactoryOptions);
        this.byteArrayPool.put(bytesForOptions);
    }
    return var14;
}

通过上面步骤,基本解码流程就结束了,加下来进入解码和发布流程

7.解码和发布

解码和发布,就是将Bitmap显示到ImageView,这里的入口在notifyEncodeAndRelease中,代码回到DecodeJob中。

// 4.1 解码和发布流程入口 @DecodeJob.java
private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
    ......
   	// -->4.2 开始解码和发布
    this.notifyComplete((Resource)result, dataSource);
    // 设置stage为ENCODE
    this.stage = DecodeJob.Stage.ENCODE;
	......
 }
 
 //4.2 开始解码和发布 @DecodeJob.java
 private void notifyComplete(Resource<R> resource, DataSource dataSource) {
     this.setNotifiedOrThrow();
     // -->4.3 回调EngineJob.onResourceReady
     this.callback.onResourceReady(resource, dataSource);
 }
 
 // 4.3 @EngineJob.java
 public void onResourceReady(Resource<R> resource, DataSource dataSource) {
     synchronized(this) {
     	this.resource = resource;
     	this.dataSource = dataSource;
     }
     // -->4.4
	this.notifyCallbacksOfResult();
}
// 4.4 @EngineJob.java
void notifyCallbacksOfResult() {
       ......
       // -->4.5
       while(var4.hasNext()) {
            EngineJob.ResourceCallbackAndExecutor entry = (EngineJob.ResourceCallbackAndExecutor)var4.next();
            entry.executor.execute(new EngineJob.CallResourceReady(entry.cb));
        }
}
//4.5 @EngineJob.java
static final class ResourceCallbackAndExecutor {
	while(var4.hasNext()) {
    	EngineJob.ResourceCallbackAndExecutor entry = (EngineJob.ResourceCallbackAndExecutor)var4.next();
        entry.executor.execute(new EngineJob.CallResourceReady(entry.cb)); //-->4.6
    }
}
//4.6 @EngineJob.java
private class CallResourceReady implements Runnable {
    public void run() {
    ......
    // -->4.7 
    EngineJob.this.callCallbackOnResourceReady(this.cb);
	......
    }
}
//4.7 @EngineJob.java
void callCallbackOnResourceReady(ResourceCallback cb) {
	try {
		//-->4.8 这里的回调cb指的传的就是SingleRequest,在2.6中 SingleRequest中把自身作为倒数第二个参数传入engine.load中
    	cb.onResourceReady(this.engineResource, this.dataSource);
     } catch (Throwable var3) {
        throw new CallbackException(var3);
     }
}
// 4.8 @SingleRequest.java
private void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
    ......
      if (!anyListenerHandledUpdatingTarget) {
        Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
        //-->4.9 这里的target便是我们调用之初建立的BitmapImageViewTarget,具体的实现方法在其父类ImageViewTarget中
        target.onResourceReady(result, animation);
      }
	......
  }
// 4.9 @ImageViewTarget.java
 @Override
  public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
    if (transition == null || !transition.transition(resource, this)) {
      setResourceInternal(resource); //-->4.10
    } else {
      maybeUpdateAnimatable(resource);
    }
  }
  
  //4.10 @ImageViewTarget.java
  private void setResourceInternal(@Nullable Z resource) {
  	//-->4.11 抽象方法,具体实现在子类BitmapImageViewTarget中
    setResource(resource);
    maybeUpdateAnimatable(resource);
  }
  
  //4.11 @BitmapImageView.java
  @Override
  protected void setResource(Bitmap resource) {
  	//终于看到了Bitmap设置到imageView上!
    view.setImageBitmap(resource);
  }
 

从上面分析流程可知,Gilde大多数的处理流程都在into方法中执行,请求,数据,编码解码,以及最后的显示,这份源码值得我们多读几次,细细品味。
文章虽然很长,但是我还是决定不分篇,以保证加载流程阅读的完整度,也方便后期检索方便。很感谢看到最后的各位~

参考
Glide4.8源码拆解(二)核心加载流程
Glide4.10 缓存
LruCache缓存机制

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章