RequestBuilder是什么
它是一个用于处理设置选项和启动加载的类,可以用来监听资源的加载成功与否(RequestListener),加载失败(error)和缩略图(thumbnail),创建Target和Request等。
RequestBuilder怎么创建的
在RequestManger里我们调用load()加载资源的时候,最终会调用RequestBuilder的构造方法把RequestManager和资源的类型赋值进去并创建一个RequestBuilder。
GlideApp.with(context)
.load(url)
.into(imageView)
//RequestManager
public RequestBuilder load(@Nullable String string) {
return asDrawable().load(string);
}
public RequestBuilder asDrawable() {
return as(Drawable.class);
}
public RequestBuilder as(
@NonNull Class resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
load()里面做了什么
这里只是简单的进行赋值,并把isModelSet设置为true。
public RequestBuilder load(@Nullable String string) {
return loadGeneric(string);
}
private RequestBuilder loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
into()里面做了什么
首先会判断如果之前没有设置转换比如调用centerCrop()并且允许转换而且imageView的scaleType不为null,则根据它的scaleType设置相应的转换。然后创建了一个ImageViewTarget对象并且传入了into的重载方法。
public ViewTarget into(@NonNull ImageView view) {
BaseRequestOptions> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
switch (view.getScaleType()) {
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.
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
ImageViewTarget的创建
这里使用了工厂模式来创建ViewTarget,由上面可知我们的资源类型是Drawable,则最终会创建一个DrawableImageViewTarget。
public ViewTarget buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
public ViewTarget buildTarget(@NonNull ImageView view,
@NonNull Class clazz) {
if (Bitmap.class.equals(clazz)) {
return (ViewTarget) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (ViewTarget) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException(
"Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
Request的创建
这里通过buildRequest()方法创建了一个Request,并且判断是否和Target之前的Request相等以及如果使用内存缓存的话则回收掉刚刚创建的Request。
> Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
Executor callbackExecutor) {
return into(target, targetListener, /*options=*/ this, callbackExecutor);
}
private > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
BaseRequestOptions> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
if (!isModelSet) {
//如果没有调用load()方法则会抛异常
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest(); //调用view.getTag()获取Request
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin(); //如果之前的Request不是正在运行的,则开始执行
}
return target;
}
requestManager.clear(target); //清除request并释放资源
target.setRequest(request); //调用view.setTag()保存request
requestManager.track(target, request);
return target;
}
Request的具体创建
通过几个重载方法,把一堆参数最后传给了SingleRequest的构造方法来创建SingleRequest,由于Request可能会比较多,所以Glide使用了对象池来对SingleRequest进行复用。
private Request buildRequest(
Target target,
@Nullable RequestListener targetListener,
BaseRequestOptions> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(
target,
targetListener,
/*parentCoordinator=*/ null,
transitionOptions,
requestOptions.getPriority(),
requestOptions.getOverrideWidth(),
requestOptions.getOverrideHeight(),
requestOptions,
callbackExecutor);
}
private Request buildRequestRecursive(
Target target,
@Nullable RequestListener targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions> requestOptions,
Executor callbackExecutor) {
Request mainRequest =
buildThumbnailRequestRecursive(
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
if (errorRequestCoordinator == null) {
return mainRequest;
}
}
private Request buildThumbnailRequestRecursive(
Target target,
RequestListener targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions> requestOptions,
Executor callbackExecutor) {
return obtainRequest(
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
private Request obtainRequest(
Target target,
RequestListener targetListener,
BaseRequestOptions> requestOptions,
RequestCoordinator requestCoordinator,
TransitionOptions, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
Executor callbackExecutor) {
return SingleRequest.obtain(
context,
glideContext,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
glideContext.getEngine(),
transitionOptions.getTransitionFactory(),
callbackExecutor);
}
public static SingleRequest obtain(
Context context,
GlideContext glideContext,
Object model,
Class transcodeClass,
BaseRequestOptions> requestOptions,
int overrideWidth,
int overrideHeight,
Priority priority,
Target target,
RequestListener targetListener,
@Nullable List> requestListeners,
RequestCoordinator requestCoordinator,
Engine engine,
TransitionFactory super R> animationFactory,
Executor callbackExecutor) {
@SuppressWarnings("unchecked") SingleRequest request =
(SingleRequest) POOL.acquire();
if (request == null) {
request = new SingleRequest<>();
}
request.init(
context,
glideContext,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
engine,
animationFactory,
callbackExecutor);
return request;
}
到此Target和Request都创建完成了,接着会调用RequestManger的track()把它们传递进去,在上文Glide源码解析之监听生命周期我们介绍过TargetTracker和RequestTracker,他们追踪的Target和Request就是在这里赋值的。
//RequestManager
synchronized void track(@NonNull Target> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
//RequestTracker
/**
* 对request开始追踪
*/
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");
}
pendingRequests.add(request);
}
}