if (animationExecutor == null) {
 animationExecutor = GlideExecutor.newAnimationExecutor();
 }
if (memorySizeCalculator == null) {
 memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
 }
if (connectivityMonitorFactory == null) {
 connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
 }
if (bitmapPool == null) {
 // 依据设备的屏幕密度和尺寸设置各种pool的size
 int size = memorySizeCalculator.getBitmapPoolSize();
 if (size > 0) {
 // 创建图片线程池LruBitmapPool,缓存所有被释放的bitmap
 // 缓存策略在API大于19时,为SizeConfigStrategy,小于为AttributeStrategy。
 // 其中SizeConfigStrategy是以bitmap的size和config为key,value为bitmap的HashMap
 bitmapPool = new LruBitmapPool(size);
 } else {
 bitmapPool = new BitmapPoolAdapter();
 }
 }
// 创建对象数组缓存池LruArrayPool,默认4M
 if (arrayPool == null) {
 arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSiz eInBytes());
 }
// 创建LruResourceCache,内存缓存
 if (memoryCache == null) {
 memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCa cheSize());
 }
if (diskCacheFactory == null) {
 diskCacheFactory = new InternalCacheDiskCacheFactory(context);
 }
// 创建任务和资源管理引擎(线程池,内存缓存和硬盘缓存对象)
 if (engine == null) {
 engine =
 new Engine(
 memoryCache,
 diskCacheFactory,
 diskCacheExecutor,
 sourceExecutor,
 GlideExecutor.newUnlimitedSourceExecutor( ),
 GlideExecutor.newAnimationExecutor(),
 isActiveResourceRetentionAllowed);
 }
RequestManagerRetriever requestManagerRetriever =
 new RequestManagerRetriever(requestManagerFactory);
return new Glide(
 context,
 engine,
 memoryCache,
 bitmapPool,
 arrayPool,
 requestManagerRetriever,
 connectivityMonitorFactory,
 logLevel,
 defaultRequestOptions.lock(),
 defaultTransitionOptions);
 }
4、Glide#Glide构造方法
Glide(…) {
 …
 // 注册管理任务执行对象的类(Registry)
 // Registry是一个工厂,而其中所有注册的对象都是一个工厂员工,当任务分发时,
 // 根据当前任务的性质,分发给相应员工进行处理
 registry = new Registry();
…
// 这里大概有60余次的append或register员工组件(解析器、编解码器、工厂类、转码类等等组件)
 registry
 .append(ByteBuffer.class, new ByteBufferEncoder())
 .append(InputStream.class, new StreamEncoder(arrayPool))
// 根据给定子类产出对应类型的target(BitmapImageViewTarget / DrawableImageViewTarget)
 ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
glideContext =
 new GlideContext(
 context,
 arrayPool,
 registry,
 imageViewTargetFactory,
 defaultRequestOptions,
 defaultTransitionOptions,
 engine,
 logLevel);
 }
5、RequestManagerRetriever#get
@NonNull
 public RequestManager get(@NonNull Context context) {
 if (context == null) {
 throw new IllegalArgumentException(“You cannot start a load on a null Context”);
 } else if (Util.isOnMainThread() && !(context instanceof Application)) {
 // 如果当前线程是主线程且context不是Application走相应的get重载方法
 if (context instanceof FragmentActivity) {
 return get((FragmentActivity) context);
 } else if (context instanceof Activity) {
 return get((Activity) context);
 } else if (context instanceof ContextWrapper) {
 return get(((ContextWrapper) context).getBaseContext());
 }
 }
// 否则直接将请求与ApplicationLifecycle关联
 return getApplicationManager(context);
 }
这里总结一下,对于当前传入的context是application或当前线程是子线程时,请求的生命周期和ApplicationLifecycle关联,否则,context是FragmentActivity或Fragment时,在当前组件添加一个SupportFragment(SupportRequestManagerFragment),context是Activity时,在当前组件添加一个Fragment(RequestManagerFragment)。
6、GlideApp#with小结
1、初始化各式各样的配置信息(包括缓存,请求线程池,大小,图片格式等等)以及glide对象。
2、将glide请求和application/SupportFragment/Fragment的生命周期绑定在一块。
这里我们再回顾一下with方法的执行流程。

三、load(url)源码详解
1、GlideRequest(RequestManager)#load
return (GlideRequest) super.load(string);
return asDrawable().load(string);
// 1、asDrawable部分
 return (GlideRequest) super.asDrawable();
return as(Drawable.class);
// 最终返回了一个GlideRequest(RequestManager的子类)
 return new GlideRequest<>(glide, this, resourceClass, context);
// 2、load部分
 return (GlideRequest) super.load(string);
return loadGeneric(string);
@NonNull
 private RequestBuilder loadGeneric(@Nullable Object model) {
 // model则为设置的url
 this.model = model;
 // 记录url已设置
 isModelSet = true;
 return this;
 }
可以看到,load这部分的源码很简单,就是给GlideRequest(RequestManager)设置了要请求的mode(url),并记录了url已设置的状态。
这里,我们再看看load方法的执行流程。

四、into(iv)源码详解
前方预警,真正复杂的地方开始了。
1、RequestBuilder.into
@NonNull
 public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
 Util.assertMainThread();
 Preconditions.checkNotNull(view);
RequestOptions requestOptions = this.requestOptions;
 if (!requestOptions.isTransformationSet()
 && requestOptions.isTransformationAllowed()
 && view.getScaleType() != null) {
 // Clone in this method so that if we use this RequestBuilder to load into a View and then
 // into a different target, we don’t retain the transformation applied based on the previous
 // View’s scale type.
 switch (view.getScaleType()) {
 // 这个RequestOptions里保存了要设置的scaleType,Glide自身封装了CenterCrop、CenterInside、
 // FitCenter、CenterInside四种规格。
 case CENTER_CROP:
 requestOptions = requestOptions.clone().optionalCenterCrop();
 break;
 case CENTER_INSIDE:
 requestOptions = requestOptions.clone().optionalCenterInside() ;
 break;
 case FIT_CENTER:
 case FIT_START:
 case FIT_END:
 requestOptions = requestOptions.clone().optionalFitCenter();
 break;
 case FIT_XY:
 requestOptions = requestOptions.clone().optionalCenterInside() ;
 break;
 case CENTER:
 case MATRIX:
 default:
 // Do nothing.
 }
 }
// 注意,这个transcodeClass是指的drawable或bitmap
 return into(
 glideContext.buildImageViewTarget(view, transcodeClass),
 /targetListener=/ null,
 requestOptions);
 }
2、GlideContext#buildImageViewTarget
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
3、ImageViewTargetFactory#buildTarget
@NonNull
 @SuppressWarnings(“unchecked”)
 public ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
 @NonNull Class clazz) {
 // 返回展示Bimtap/Drawable资源的目标对象
 if (Bitmap.class.equals(clazz)) {
 return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
 } else if (Drawable.class.isAssignableFrom(clazz)) {
 return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
 } else {
 throw new IllegalArgumentException(
 "Unhandled class: " + clazz + “, try .as*(Class).transcode(ResourceTranscoder)”);
 }
 }
可以看到,Glide内部只维护了两种target,一种是BitmapImageViewTarget,另一种则是DrawableImageViewTarget,接下来继续深入。
4、RequestBuilder#into
private <Y extends Target> Y into(
 @NonNull Y target,
 @Nullable RequestListener targetListener,
 @NonNull RequestOptions options) {
 Util.assertMainThread();
 Preconditions.checkNotNull(target);
 if (!isModelSet) {
 throw new IllegalArgumentException(“You must call #load() before calling #into()”);
 }
options = options.autoClone();
 // 分析1.建立请求
 Request request = buildRequest(target, targetListener, options);
Request previous = target.getRequest();
 if (request.isEquivalentTo(previous)
 && !isSkipMemoryCacheWithCompletePreviousReques t(options, previous)) {
 request.recycle();
 // If the request is completed, beginning again will ensure the result is re-delivered,
 // triggering RequestListeners and Targets. If the request is failed, beginning again will
 // restart the request, giving it another chance to complete. If the request is already
 // running, we can let it continue running without interruption.
 if (!Preconditions.checkNotNull(previous).isRunni ng()) {
 // Use the previous request rather than the new one to allow for optimizations like skipping
 // setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
 // that are done in the individual Request.
 previous.begin();
 }
 return target;
 }
requestManager.clear(target);
 target.setRequest(request);
 // 分析2.真正追踪请求的地方
 requestManager.track(target, request);
return target;
 }
// 分析1
 private Request buildRequest(
 Target target,
 @Nullable RequestListener targetListener,
 RequestOptions requestOptions) {
 return buildRequestRecursive(
 target,
 targetListener,
 /parentCoordinator=/ null,
 transitionOptions,
 requestOptions.getPriority(),
 requestOptions.getOverrideWidth(),
 requestOptions.getOverrideHeight(),
 requestOptions);
 }
// 分析1
 private Request buildRequestRecursive(
 Target target,
 @Nullable RequestListener targetListener,
 @Nullable RequestCoordinator parentCoordinator,
 TransitionOptions<?, ? super TranscodeType> transitionOptions,
 Priority priority,
 int overrideWidth,
 int overrideHeight,
 RequestOptions requestOptions) {
// Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
 ErrorRequestCoordinator errorRequestCoordinator = null;
 if (errorBuilder != null) {
 // 创建errorRequestCoordinator(异常处理对象)
 errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
 parentCoordinator = errorRequestCoordinator;
 }
// 递归建立缩略图请求
 Request mainRequest =
 buildThumbnailRequestRecursive(
 target,
 targetListener,
 parentCoordinator,
 transitionOptions,
 priority,
 overrideWidth,
 overrideHeight,
 requestOptions);
if (errorRequestCoordinator == null) {
 return mainRequest;
 }
…
Request errorRequest = errorBuilder.buildRequestRecursive(
 target,
 targetListener,
 errorRequestCoordinator,
 errorBuilder.transitionOptions,
 errorBuilder.requestOptions.getPriority(),
 errorOverrideWidth,
 errorOverrideHeight,
 errorBuilder.requestOptions);
 errorRequestCoordinator.setRequests(mainRequest, errorRequest);
 return errorRequestCoordinator;
 }
// 分析1
 private Request buildThumbnailRequestRecursive(
 Target target,
 RequestListener targetListener,
 @Nullable RequestCoordinator parentCoordinator,
 TransitionOptions<?, ? super TranscodeType> transitionOptions,
 Priority priority,
 int overrideWidth,
 int overrideHeight,
 RequestOptions requestOptions) {
 if (thumbnailBuilder != null) {
 // Recursive case: contains a potentially recursive thumbnail request builder.
…
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
 // 获取一个正常请求对象
 Request fullRequest =
 obtainRequest(
 target,
 targetListener,
 requestOptions,
 coordinator,
 transitionOptions,
 priority,
 overrideWidth,
 overrideHeight);
 isThumbnailBuilt = true;
 // Recursively generate thumbnail requests.
 // 使用递归的方式建立一个缩略图请求对象
 Request thumbRequest =
 thumbnailBuilder.buildRequestRecursive(
 target,
 targetListener,
 coordinator,
 thumbTransitionOptions,
 thumbPriority,
 thumbOverrideWidth,
 thumbOverrideHeight,
 thumbnailBuilder.requestOptions);
 isThumbnailBuilt = false;
 // coordinator(ThumbnailRequestCoordinator)是作为两者的协调者,
 // 能够同时加载缩略图和正常的图的请求
 coordinator.setRequests(fullRequest, thumbRequest);
 return coordinator;
 } else if (thumbSizeMultiplier != null) {
 // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
 // 当设置了缩略的比例thumbSizeMultiplier(0 ~ 1)时,
 // 不需要递归建立缩略图请求
 ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
 Request fullRequest =
 obtainRequest(
 target,
 targetListener,
 requestOptions,
 coordinator,
 transitionOptions,
 priority,
 overrideWidth,
 overrideHeight);
 RequestOptions thumbnailOptions = requestOptions.clone()
 .sizeMultiplier(thumbSizeMultiplier);
Request thumbnailRequest =
 obtainRequest(
 target,
 targetListener,
 thumbnailOptions,
 coordinator,
 transitionOptions,
 getThumbnailPriority(priority),
 overrideWidth,
 overrideHeight);
coordinator.setRequests(fullRequest, thumbnailRequest);
 return coordinator;
 } else {
 // Base case: no thumbnail.
 // 没有缩略图请求时,直接获取一个正常图请求
 return obtainRequest(
 target,
 targetListener,
 requestOptions,
 parentCoordinator,
 transitionOptions,
 priority,
 overrideWidth,
 overrideHeight);
 }
 }
private Request obtainRequest(
 Target target,
 RequestListener targetListener,
 RequestOptions requestOptions,
 RequestCoordinator requestCoordinator,
 TransitionOptions<?, ? super TranscodeType> transitionOptions,
 Priority priority,
 int overrideWidth,
 int overrideHeight) {
 // 最终实际返回的是一个SingleRequest对象(将制定的资源加载进对应的Target
 return SingleRequest.obtain(
 context,
 glideContext,
 model,
 transcodeClass,
 requestOptions,
 overrideWidth,
 overrideHeight,
 priority,
 target,
 targetListener,
 requestListeners,
 requestCoordinator,
 glideContext.getEngine(),
 transitionOptions.getTransitionFactory());
 }
从上源码分析可知,我们在分析1处的buildRequest()方法里建立了请求,且最多可同时进行缩略图和正常图的请求,最后,调用了requestManager.track(target, request)方法,接着看看track里面做了什么。
5、RequestManager#track
// 分析2
 void track(@NonNull Target<?> target, @NonNull Request request) {
 // 加入一个target目标集合(Set)
 targetTracker.track(target);
requestTracker.runRequest(request);
 }
6、RequestTracker#runRequest
/**
- Starts tracking the given request.
*/
// 分析2
public void runRequest(@NonNull Request request) {
requests.add(request);
if (!isPaused) {
// 如果不是暂停状态则开始请求
request.begin();
} else {
request.clear();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, “Paused, delaying request”);
}
// 否则清空请求,加入延迟请求队列(为了对这些请求维持一个强引用,使用了ArrayList实现)
pendingRequests.add(request);
}
} 
7、SingleRequest#begin
// 分析2
 @Override
 public void begin() {
…
if (model == null) {
…
 // model(url)为空,回调加载失败
 onLoadFailed(new GlideException(“Received null model”), logLevel);
 return;
 }
if (status == Status.RUNNING) {
 throw new IllegalArgumentException(“Cannot restart a running request”);
 }
if (status == Status.COMPLETE) {
 onResourceReady(resource, DataSource.MEMORY_CACHE);
 return;
 }
status = Status.WAITING_FOR_SIZE;
 if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
 // 当使用override() API为图片指定了一个固定的宽高时直接执行onSizeReady,
 // 最终的核心处理位于onSizeReady
 onSizeReady(overrideWidth, overrideHeight);
 } else {
 // 根据imageView的宽高算出图片的宽高,最终也会走到onSizeReady
 target.getSize(this);
 }
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
 && canNotifyStatusChanged()) {
 // 预先加载设置的缩略图
 target.onLoadStarted(getPlaceholderDrawable());
 }
 if (IS_VERBOSE_LOGGABLE) {
 logV("finished run method in " + LogTime.getElapsedMillis(startTime));
 }
 }
从requestManager.track(target, request)开始,最终会执行到SingleRequest#begin()方法的onSizeReady,可以猜到(因为后面只做了预加载缩略图的处理),真正的请求就是从这里开始的,咱们进去一探究竟~
8、SingleRequest#onSizeReady
// 分析2
 @Override
 public void onSizeReady(int width, int height) {
 stateVerifier.throwIfRecycled();
…
status = Status.RUNNING;
float sizeMultiplier = requestOptions.getSizeMultiplier();
 this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
 this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
…
// 根据给定的配置进行加载,engine是一个负责加载、管理活跃和缓存资源的引擎类
 loadStatus = engine.load(
 glideCon
 text,
 model,
 requestOptions.getSignature(),
 this.width,
 this.height,
 requestOptions.getResourceClass(),
 transcodeClass,
 priority,
 requestOptions.getDiskCacheStrategy(),
 requestOptions.getTransformations(),
 requestOptions.isTransformationRequired(),
 requestOptions.isScaleOnlyOrNoTransform(),
 requestOptions.getOptions(),
 requestOptions.isMemoryCacheable(),
 requestOptions.getUseUnlimitedSourceGeneratorsP ool(),
 requestOptions.getUseAnimationPool(),
 requestOptions.getOnlyRetrieveFromCache(),
 this);
…
 }
终于看到Engine类了,感觉距离成功不远了,继续~
9、Engine#load
public LoadStatus load(
 GlideContext glideContext,
 Object model,
 Key signature,
 int width,
 int height,
 Class<?> resourceClass,
 Class transcodeClass,
 Priority priority,
 DiskCacheStrategy diskCacheStrategy,
 Map<Class<?>, Transformation<?>> transformations,
 boolean isTransformationRequired,
 boolean isScaleOnlyOrNoTransform,
 Options options,
 boolean isMemoryCacheable,
 boolean useUnlimitedSourceExecutorPool,
 boolean useAnimationPool,
 boolean onlyRetrieveFromCache,
 ResourceCallback cb) {
…
// 先从弱引用中查找,如果有的话回调onResourceReady并直接返回
 EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
 if (active != null) {
 cb.onResourceReady(active, DataSource.MEMORY_CACHE);
 if (VERBOSE_IS_LOGGABLE) {
 logWithTimeAndKey(“Loaded resource from active resources”, startTime, key);
 }
 return null;
 }
// 没有再从内存中查找,有的话会取出并放到ActiveResources(内部维护的弱引用缓存map)里面
 EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
 if (cached != null) {
 cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
 if (VERBOSE_IS_LOGGABLE) {
 logWithTimeAndKey(“Loaded resource from cache”, startTime, key);
 }
 return null;
 }
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
 if (current != null) {
 current.addCallback(cb);
 if (VERBOSE_IS_LOGGABLE) {
 logWithTimeAndKey(“Added to existing load”, startTime, key);
 }
 return new LoadStatus(cb, current);
 }
// 如果内存中没有,则创建engineJob(decodejob的回调类,管理下载过程以及状态)
 EngineJob engineJob =
 engineJobFactory.build(
 key,
 isMemoryCacheable,
 useUnlimitedSourceExecutorPool,
 useAnimationPool,
 onlyRetrieveFromCache);
// 创建解析工作对象
 DecodeJob decodeJob =
 decodeJobFactory.build(
 glideContext,
 model,
 key,
 signature,
 width,
 height,
 resourceClass,
 transcodeClass,
 priority,
 diskCacheStrategy,
 transformations,
 isTransformationRequired,
 isScaleOnlyOrNoTransform,
 onlyRetrieveFromCache,
 options,
 engineJob);
// 放在Jobs内部维护的HashMap中
 jobs.put(key, engineJob);
// 关注点8 后面分析会用到
 // 注册ResourceCallback接口
 engineJob.addCallback(cb);
 // 内部开启线程去请求
 engineJob.start(decodeJob);
if (VERBOSE_IS_LOGGABLE) {
 logWithTimeAndKey(“Started new load”, startTime, key);
 }
 return new LoadStatus(cb, engineJob);
 }
public void start(DecodeJob decodeJob) {
 this.decodeJob = decodeJob;
 // willDecodeFromCache方法内部根据不同的阶段stage,如果是RESOURCE_CACHE/DATA_CACHE则返回true,使用diskCacheExecutor,否则调用getActiveSourceExecutor,内部会根据相应的条件返回sourceUnlimitedExecutor/animationExecutor/sourceExecutor
 GlideExecutor executor =
 decodeJob.willDecodeFromCache()
 ? diskCacheExecutor
 : getActiveSourceExecutor();
 executor.execute(decodeJob);
 }
可以看到,最终Engine(引擎)类内部会执行到自身的start方法,它会根据不同的配置采用不同的线程池使用diskCacheExecutor/sourceUnlimitedExecutor/animationExecutor/sourceExecutor来执行最终的解码任务decodeJob。
10、DecodeJob#run
runWrapped();
private void runWrapped() {
 switch (runReason) {
 case INITIALIZE:
 stage = getNextStage(Stage.INITIALIZE);
 // 关注点1
 currentGenerator = getNextGenerator();
 // 关注点2 内部会调用相应Generator的startNext()
 runGenerators();
 break;
 case SWITCH_TO_SOURCE_SERVICE:
 runGenerators();
 break;
 case DECODE_DATA:
 // 关注点3 将获取的数据解码成对应的资源
 decodeFromRetrievedData();
 break;
 default:
 throw new IllegalStateException("Unrecognized run reason: " + runReason);
 }
 }
// 关注点1,完整情况下,会异步依次生成这里的ResourceCacheGenerator、DataCacheGenerator和SourceGenerator对象,并在之后执行其中的startNext()
 private DataFetcherGenerator getNextGenerator() {
 switch (stage) {
 case RESOURCE_CACHE:
 return new ResourceCacheGenerator(decodeHelper, this);
 case DATA_CACHE:
 return new DataCacheGenerator(decodeHelper, this);
 case SOURCE:
 return new SourceGenerator(decodeHelper, this);
 case FINISHED:
 return null;
 default:
 throw new IllegalStateException("Unrecognized stage: " + stage);
 }
 }
11、SourceGenerator#startNext
// 关注点2
 @Override
 public boolean startNext() {
 // dataToCache数据不为空的话缓存到硬盘(第一执行该方法是不会调用的)
 if (dataToCache != null) {
 Object data = dataToCache;
 dataToCache = null;
 cacheData(data);
 }
if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
 return true;
 }
 sourceCacheGenerator = null;
loadData = null;
 boolean started = false;
 while (!started && hasNextModelLoader()) {
 // 关注点4 getLoadData()方法内部会在modelLoaders里面找到ModelLoder对象
 // (每个Generator对应一个ModelLoader),
 // 并使用modelLoader.buildLoadData方法返回一个loadData列表
 loadData = helper.getLoadData().get(loadDataListIndex++);
 if (loadData != null
 && (helper.getDiskCacheStrategy().isDataCache able(loadData.fetcher.getDataSource())
 || helper.hasLoadPath(loadData.fetcher.getDat aClass()))) {
 started = true;
 // 关注点6 通过loadData对象的fetcher对象(有关注点3的分析可知其实现类为HttpUrlFetcher)的
 // loadData方法来获取图片数据
 loadData.fetcher.loadData(helper.getPriority(), this);
 }
 }
 return started;
 }
12、DecodeHelper#getLoadData
List<LoadData<?>> getLoadData() {
 if (!isLoadDataSet) {
 isLoadDataSet = true;
 loadData.clear();
 List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model) ;
 //noinspection ForLoopReplaceableByForEach to improve perf
 for (int i = 0, size = modelLoaders.size(); i < size; i++) {
 ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
 // 注意:这里最终是通过HttpGlideUrlLoader的buildLoadData获取到实际的loadData对象
 LoadData<?> current =
 modelLoader.buildLoadData(model, width, height, options);
 if (current != null) {
 loadData.add(current);
 }
 }
 }
 return loadData;
 }
13、HttpGlideUrlLoader#buildLoadData
@Override
 public LoadData buildLoadData(@NonNull GlideUrl model, int width, int height,
 @NonNull Options options) {
 // GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time
 // spent parsing urls.
 GlideUrl url = model;
 if (modelCache != null) {
 url = modelCache.get(model, 0, 0);
 if (url == null) {
 // 关注点5
 modelCache.put(model, 0, 0, model);
 url = model;
 }
 }
 int timeout = options.get(TIMEOUT);
 // 注意,这里创建了一个DataFetcher的实现类HttpUrlFetcher
 return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
 }
// 关注点5
 public void put(A model, int width, int height, B value) {
 ModelKey key = ModelKey.get(model, width, height);
 // 最终是通过LruCache来缓存对应的值,key是一个ModelKey对象(由model、width、height三个属性组成)
 cache.put(key, value);
 }
从这里的分析,我们明白了HttpUrlFetcher实际上就是最终的请求执行者,而且,我们知道了Glide会使用LruCache来对解析后的url来进行缓存,以便后续可以省去解析url的时间。
14、HttpUrlFetcher#loadData
@Override
 public void loadData(@NonNull Priority priority,
 @NonNull DataCallback<? super InputStream> callback) {
 long startTime = LogTime.getLogTime();
 try {
 // 关注点6
 // loadDataWithRedirects内部是通过HttpURLConnection网络请求数据
 InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
 // 请求成功回调onDataReady()
 callback.onDataReady(result);
 } catch (IOException e) {
 if (Log.isLoggable(TAG, Log.DEBUG)) {
 Log.d(TAG, “Failed to load data for url”, e);
 }
 callback.onLoadFailed(e);
 } finally {
 if (Log.isLoggable(TAG, Log.VERBOSE)) {
 Log.v(TAG, "Finished http url fetcher fetch in " + LogTime.getElapsedMillis(startTime));
 }
 }
 }
private InputStream loadDataWithRedirects(URL url, int redirects, URL lastUrl,
 Map<String, String> headers) throws IOException {
…
urlConnection.connect();
 // Set the stream so that it’s closed in cleanup to avoid resource leaks. See #2352.
 stream = urlConnection.getInputStream();
 if (isCancelled) {
 return null;
 }
 final int statusCode = urlConnection.getResponseCode();
 // 只要是2xx形式的状态码则判断为成功
 if (isHttpOk(statusCode)) {
 // 从urlConnection中获取资源流
 return getStreamForSuccessfulRequest(urlConnection);
 } else if (isHttpRedirect(statusCode)) {
…
// 重定向请求
 return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
 } else if (statusCode == INVALID_STATUS_CODE) {
 throw new HttpException(statusCode);
 } else {
 throw new HttpException(urlConnection.getResponseMessage(), statusCode);
 }
 }
url fetcher fetch in " + LogTime.getElapsedMillis(startTime));
 }
 }
 }
private InputStream loadDataWithRedirects(URL url, int redirects, URL lastUrl,
 Map<String, String> headers) throws IOException {
…
urlConnection.connect();
 // Set the stream so that it’s closed in cleanup to avoid resource leaks. See #2352.
 stream = urlConnection.getInputStream();
 if (isCancelled) {
 return null;
 }
 final int statusCode = urlConnection.getResponseCode();
 // 只要是2xx形式的状态码则判断为成功
 if (isHttpOk(statusCode)) {
 // 从urlConnection中获取资源流
 return getStreamForSuccessfulRequest(urlConnection);
 } else if (isHttpRedirect(statusCode)) {
…
// 重定向请求
 return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
 } else if (statusCode == INVALID_STATUS_CODE) {
 throw new HttpException(statusCode);
 } else {
 throw new HttpException(urlConnection.getResponseMessage(), statusCode);
 }
 }










