基于源码4.9.0分析,不同版本可能会有所差异,先说整体,后面分节说细节!
Glide最简单的使用就是Glide.with(this).load(url).into(view),我们注意分析这个过程发生了什么。
一、初始化Glide,创建RequestManager
Glide.with(this)
,这里主要是使用GlideBuilder
生成Glide
,通过Glide
获取RequestManagerRetriever
生成一个RequestManager
对象。
在初始化Glide的时候,有2种方式获取GlideModule
。
1、通过编译时注解处理器AnnotationProcessor
动态生成。
2、androidmenifest
上通过metadata
标记。
//Glide.java
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
Context applicationContext = context.getApplicationContext();
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
...
}
二、创建Requestbuilder
load(url)
。load方法重载了很多个,举例子说其中一个。
//RequestManager.java
public RequestBuilder<Drawable> load(@Nullable Uri uri) {
return asDrawable().load(uri);
}
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
//RequestBuilder.java
protected RequestBuilder(
@NonNull Glide glide,
RequestManager requestManager,
Class<TranscodeType> transcodeClass,
Context context) {
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());
}
这里有一点需要注意的,as
方法里面的resourceClass
参数,在requestBuilder
里其实是transcodeClass
,requestBuilder
的父类BaseRequestOptions
里面resourceClass
默认值是object.class
。那么transcodeClass
和resourceClass
的作用是什么呢?详情可见Glide4.9.0 数据转换设计思路
三、创建request开始任务
into(view)
//RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
//这里的target将会给singleRequest用于任务结果回调
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(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).isRunning()) {
// 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);
requestManager.track(target, request);
return target;
}
这里主要做了3件事情
1、利用递归创建request
。 GLide buildRequestRecursive 源码解析
2、判断是不是已经存在request
,有的话,直接begin()
。
3、放到requestmanager
保存,调用request.begin()
SingleRequest是Request接口的实现类,可以看到在begin方法中有一个onSizeReady的判断。其中overrideWidth和overrideHeigth可以通过RequestOptions.overrideOf方法设置。假如没有设置,将会通过其他方法判断,这里先不展开。
最后就会调用engine.load根据前面的设置参数开始一个任务。
//SingleRequest.java
@Override
public synchronized void begin() {
...
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
target.getSize(this);
}
...
}
@Override
public synchronized void onSizeReady(int width, int height) {
...
loadStatus =
engine.load(
glideContext,
model,
requestOptions.getSignature(),
this.width,
this.height,
requestOptions.getResourceClass(),
transcodeClass,
priority,
requestOptions.getDiskCacheStrategy(),
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.isScaleOnlyOrNoTransform(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getUseAnimationPool(),
requestOptions.getOnlyRetrieveFromCache(),
this,
callbackExecutor);
...
}