分析完Glide构造的第一个步RequesManager生命周期监听和第二步RequestBuilder请求数据的封装,现在来到第三步请求的发送
Glide.with(this)
.load(uri)
.skipMemoryCache(true)
.into(iv_activity)
目录
一、将Imanage封装成Target
二、将Target组装成Request开始请求
三、处理Target重复请求
四、发送请求
一 将Imanage封装成Target
一般我们常用的都是into到ImageView中,其实最后调用的都是into(Target)
RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor)
1.1 ImageView是如何封装成Target的
RequestBuilder.java
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
//判断是否是在主线程
Util.assertMainThread();
Preconditions.checkNotNull(view);
//获取所有的配置信息
BaseRequestOptions<?> requestOptions = this;
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.
//根据scale type.进行请求配置赋值
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(
//这里开始创建Tartget
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
//所有的请求噢配置
requestOptions,
//回调线程
Executors.mainThreadExecutor());
}
1.2 获取通过工厂方法获取Target对象
glideContext.buildImageViewTarget(view, transcodeClass),
GlideContext.java
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
imageViewTargetFactory 是在创建Glide的时候new出来,然后赋值的
GlideContext.java
public GlideContext(
@NonNull Context context,
@NonNull ArrayPool arrayPool,
@NonNull Registry registry,
@NonNull ImageViewTargetFactory imageViewTargetFactory,
@NonNull RequestOptionsFactory defaultRequestOptionsFactory,
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
@NonNull List<RequestListener<Object>> defaultRequestListeners,
@NonNull Engine engine,
boolean isLoggingRequestOriginsEnabled,
int logLevel) {
super(context.getApplicationContext());
···
this.imageViewTargetFactory = imageViewTargetFactory;
···
}
Glide.java
Glide(
@NonNull Context context,
@NonNull Engine engine,
@NonNull MemoryCache memoryCache,
@NonNull BitmapPool bitmapPool,
@NonNull ArrayPool arrayPool,
@NonNull RequestManagerRetriever requestManagerRetriever,
@NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
int logLevel,
@NonNull RequestOptionsFactory defaultRequestOptionsFactory,
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
@NonNull List<RequestListener<Object>> defaultRequestListeners,
boolean isLoggingRequestOriginsEnabled,
boolean isImageDecoderEnabledForBitmaps) {
····
ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
glideContext =
new GlideContext(
context,
arrayPool,
registry,
imageViewTargetFactory,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
engine,
isLoggingRequestOriginsEnabled,
logLevel);
}
ImageViewTargetFactory是一个工厂类,根据输入类型返回对应的Tartget,之前我们在调用glideContext.buildImageViewTarget(view, transcodeClass),传入的ImageView,所以返回的是BitmapImageViewTarget
ImageViewTargetFactory
public class ImageViewTargetFactory {
@NonNull
@SuppressWarnings("unchecked")
public <Z> ViewTarget<ImageView, Z> buildTarget(
@NonNull ImageView view, @NonNull Class<Z> clazz) {
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)");
}
}
}
1.3 BitmapImageViewTarget
BitmapImageViewTarget.java
public class BitmapImageViewTarget extends ImageViewTarget<Bitmap> {
// Public API.
@SuppressWarnings("WeakerAccess")
public BitmapImageViewTarget(ImageView view) {
super(view);
}
/** @deprecated Use {@link #waitForLayout()} instead. */
// Public API.
@SuppressWarnings({"unused", "deprecation"})
@Deprecated
public BitmapImageViewTarget(ImageView view, boolean waitForLayout) {
super(view, waitForLayout);
}
/**
* Sets the {@link android.graphics.Bitmap} on the view using {@link
* android.widget.ImageView#setImageBitmap(android.graphics.Bitmap)}.
*
* @param resource The bitmap to display.
*/
@Override
protected void setResource(Bitmap resource) {
//这里在请求返回成功后设置resource给ImageView
view.setImageBitmap(resource);
}
}
BitmapImageViewTarget是ImageViewTarget的子类,IamgerViewTarget控制显示成功内容和失败展位图,控制动画显示。
二 将Target组装成Request开始请求
我们知道,无论是into(ImageView)还是into(Target),最后调用的都是下面的方法
RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
//检测target不为null
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
//封装Request 2.1
Request request = buildRequest(target, targetListener, options, callbackExecutor);
···
return target;
}
2.1 封装Request
调用Request request = buildRequest(target, targetListener, options, callbackExecutor);来封装Request
RequestBuilder.java
private Request buildRequest(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(
/*requestLock=*/ new Object(),
target,
targetListener,
/*parentCoordinator=*/ null,
transitionOptions,
requestOptions.getPriority(),
requestOptions.getOverrideWidth(),
requestOptions.getOverrideHeight(),
requestOptions,
callbackExecutor);
}
2.2 封装主请求和错误图请求
RequestBuilder.java
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) {
····
ErrorRequestCoordinator errorRequestCoordinator = null;
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
//创建主图请求包括缩略图请求
Request mainRequest =
buildThumbnailRequestRecursive(
requestLock,
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
if (errorRequestCoordinator == null) {
return mainRequest;
}
···
//创建错误请求
Request errorRequest =
errorBuilder.buildRequestRecursive(
requestLock,
target,
targetListener,
errorRequestCoordinator,
errorBuilder.transitionOptions,
errorBuilder.getPriority(),
errorOverrideWidth,
errorOverrideHeight,
errorBuilder,
callbackExecutor);
errorRequestCoordinator.setRequests(mainRequest, errorRequest);
return errorRequestCoordinator;
}
2.2.1 请求协调器的封装
上面的代码最后一行 return errorRequestCoordinator;这个errorRequestCoordinator是一个Request,也是一个RequestCoordinator请求协调器,这里采用的是责任链的模式。这句errorRequestCoordinator.setRequests(mainRequest, errorRequest);表示请求的下一个请求是errorRequest,我们看一下源码
ErrorRequestCoordinator.java
public final class ErrorRequestCoordinator implements RequestCoordinator, Request {
private final Object requestLock;
@Nullable private final RequestCoordinator parent;//上一个请求
private volatile Request primary;//当前请求
private volatile Request error;//下一个请求
@GuardedBy("requestLock")
private RequestState primaryState = RequestState.CLEARED;
@GuardedBy("requestLock")
private RequestState errorState = RequestState.CLEARED;
public ErrorRequestCoordinator(Object requestLock, @Nullable RequestCoordinator parent) {
this.requestLock = requestLock;
//这里赋值,因为是主请求并带有错误请求,所以这里是null
this.parent = parent;
}
public void setRequests(Request primary, Request error) {
//这里是主请求
this.primary = primary;
//错误请求
this.error = error;
}
@Override
public void begin() {
synchronized (requestLock) {
if (primaryState != RequestState.RUNNING) {
primaryState = RequestState.RUNNING;
//主请求开始请求
primary.begin();
}
}
}
···
@Override
public void onRequestSuccess(Request request) {
synchronized (requestLock) {
//如果主请求成功设置成功状态
if (request.equals(primary)) {
primaryState = RequestState.SUCCESS;
} else if (request.equals(error)) {
//如果错误请求成功设置成功状态
errorState = RequestState.SUCCESS;
}
if (parent != null) {
//
parent.onRequestSuccess(this);
}
}
}
@Override
public void onRequestFailed(Request request) {
synchronized (requestLock) {
//主请求失败,设置状态
if (!request.equals(error)) {
primaryState = RequestState.FAILED;
if (errorState != RequestState.RUNNING) {
errorState = RequestState.RUNNING;
//开始错误请求
error.begin();
}
return;
}
errorState = RequestState.FAILED;
if (parent != null) {
parent.onRequestFailed(this);
}
}
}
@Override
public RequestCoordinator getRoot() {
synchronized (requestLock) {
return parent != null ? parent.getRoot() : this;
}
}
}
2.3 封装主图请求和缩略图请求
RequestBuilder.java
//创建缩略图请求
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 (thumbnailBuilder != null) {
// Recursive case: contains a potentially recursive thumbnail request builder.
···
TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
thumbnailBuilder.transitionOptions;
// Apply our transition by default to thumbnail requests but avoid overriding custom options
// that may have been applied on the thumbnail request explicitly.
if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
thumbTransitionOptions = transitionOptions;
}
Priority thumbPriority =
thumbnailBuilder.isPrioritySet()
? thumbnailBuilder.getPriority()
: getThumbnailPriority(priority);
···
ThumbnailRequestCoordinator coordinator =
new ThumbnailRequestCoordinator(requestLock, parentCoordinator);
//创建主图请求
Request fullRequest =
obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
isThumbnailBuilt = true;
// Recursively generate thumbnail requests.
//创建缩略图请求
Request thumbRequest =
thumbnailBuilder.buildRequestRecursive(
requestLock,
target,
targetListener,
coordinator,
thumbTransitionOptions,
thumbPriority,
thumbOverrideWidth,
thumbOverrideHeight,
thumbnailBuilder,
callbackExecutor);
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(requestLock, parentCoordinator);
//创建主图请求
Request fullRequest =
obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
BaseRequestOptions<?> thumbnailOptions =
requestOptions.clone().sizeMultiplier(thumbSizeMultiplier);
//创建缩略图请求
Request thumbnailRequest =
obtainRequest(
requestLock,
target,
targetListener,
thumbnailOptions,
coordinator,
transitionOptions,
getThumbnailPriority(priority),
overrideWidth,
overrideHeight,
callbackExecutor);
coordinator.setRequests(fullRequest, thumbnailRequest);
return coordinator;
} else {
// Base case: no thumbnail.
//没有设置缩略图,创建主图请求
return obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
}
2.4 创建请求
RequestBuilder.java
private Request obtainRequest(
Object requestLock,
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
RequestCoordinator requestCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
Executor callbackExecutor) {
return SingleRequest.obtain(
context,
glideContext,
requestLock,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
glideContext.getEngine(),
transitionOptions.getTransitionFactory(),
callbackExecutor);
}
SingleRequest.java
public static <R> SingleRequest<R> obtain(
Context context,
GlideContext glideContext,
Object requestLock,
Object model,
Class<R> transcodeClass,
BaseRequestOptions<?> requestOptions,
int overrideWidth,
int overrideHeight,
Priority priority,
Target<R> target,
RequestListener<R> targetListener,
@Nullable List<RequestListener<R>> requestListeners,
RequestCoordinator requestCoordinator,
Engine engine,
TransitionFactory<? super R> animationFactory,
Executor callbackExecutor) {
return new SingleRequest<>(
context,
glideContext,
requestLock,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
engine,
animationFactory,
callbackExecutor);
}
private SingleRequest(
Context context,
GlideContext glideContext,
@NonNull Object requestLock,
@Nullable Object model,
Class<R> transcodeClass,
BaseRequestOptions<?> requestOptions,
int overrideWidth,
int overrideHeight,
Priority priority,
Target<R> target,
@Nullable RequestListener<R> targetListener,
@Nullable List<RequestListener<R>> requestListeners,
RequestCoordinator requestCoordinator,
Engine engine,
TransitionFactory<? super R> animationFactory,
Executor callbackExecutor) {
this.requestLock = requestLock;
this.context = context;
this.glideContext = glideContext;
this.model = model;
this.transcodeClass = transcodeClass;
this.requestOptions = requestOptions;
this.overrideWidth = overrideWidth;
this.overrideHeight = overrideHeight;
this.priority = priority;
this.target = target;
this.targetListener = targetListener;
this.requestListeners = requestListeners;
this.requestCoordinator = requestCoordinator;
this.engine = engine;
this.animationFactory = animationFactory;
this.callbackExecutor = callbackExecutor;
status = Status.PENDING;
if (requestOrigin == null && glideContext.isLoggingRequestOriginsEnabled()) {
requestOrigin = new RuntimeException("Glide request origin trace");
}
}
通过静态工厂的方式创建真正的SingleRequest请求
三 处理Target重复请求
如果Target中有相同的图片请求,可以直接请求,有效提高性能
RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
//取出target之前保存的Request
Request previous = target.getRequest();
//如果target存储的请求和新创建的请求相等(包括尺寸)并且target的请求没有设置内存缓存并加载过了
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
// 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.
//target请不是在请求中
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;
}
//清除跟中的Target
requestManager.clear(target);
//设置target的Request
target.setRequest(request);
//跟中Request,并触发请求
requestManager.track(target, request);
return target;
}
private boolean isSkipMemoryCacheWithCompletePreviousRequest(
BaseRequestOptions<?> options, Request previous) {
return !options.isMemoryCacheable() && previous.isComplete();
}
四 发送请求
RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
····
requestManager.clear(target);
target.setRequest(request);
//用于触发请求
requestManager.track(target, request);
return target;
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
4.1 跟踪Tartget生命周期
targetTracker是TargetTracker用于跟踪Target生命周期
TargetTracker.java
public final class TargetTracker implements LifecycleListener {
private final Set<Target<?>> targets =
Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());
public void track(@NonNull Target<?> target) {
targets.add(target);
}
public void untrack(@NonNull Target<?> target) {
targets.remove(target);
}
@Override
public void onStart() {
for (Target<?> target : Util.getSnapshot(targets)) {
target.onStart();
}
}
@Override
public void onStop() {
for (Target<?> target : Util.getSnapshot(targets)) {
target.onStop();
}
}
@Override
public void onDestroy() {
for (Target<?> target : Util.getSnapshot(targets)) {
target.onDestroy();
}
}
@NonNull
public List<Target<?>> getAll() {
return Util.getSnapshot(targets);
}
public void clear() {
targets.clear();
}
}
4.2 跟踪Request生命周期
requestTracker是RequestTracker用于跟中Request
RequestTracker.java
public class RequestTracker {
private static final String TAG = "RequestTracker";
//跟踪所有的request
private final Set<Request> requests =
Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
/准备发送的请求
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private final List<Request> pendingRequests = new ArrayList<>();
private boolean isPaused;
/** Starts tracking the given 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);
}
}
····
4.3 执行请求
request.begin();执行的是SingleRequest的begin()方法
SingleRequest.java
@Override
public void begin() {
//同步锁
synchronized (requestLock) {
···
//如果加载完成直接调用onResourceReady
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
// Restarts for requests that are neither complete nor running can be treated as new requests
// and can run again from the beginning.
//设置等待尺寸
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
//真正请求和缓存的地方
onSizeReady(overrideWidth, overrideHeight);
} else {
//获取尺寸
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));
}
}
}
getPlaceholderDrawable()获取占位符,加载时用于显示的图片
SingleRequest.java
private Drawable getPlaceholderDrawable() {
if (placeholderDrawable == null) {
placeholderDrawable = requestOptions.getPlaceholderDrawable();
if (placeholderDrawable == null && requestOptions.getPlaceholderId() > 0) {
placeholderDrawable = loadDrawable(requestOptions.getPlaceholderId());
}
}
return placeholderDrawable;
}
target.onLoadStarted(getPlaceholderDrawable()),这个target是继承制ViewTarget,所以调用的事ViewTarget的onLoadStarted
ViewTarget.java
public void onLoadStarted(@Nullable Drawable placeholder) {
super.onLoadStarted(placeholder);
maybeAddAttachStateListener();
}
private void maybeAddAttachStateListener() {
if (attachStateListener == null || isAttachStateListenerAdded) {
return;
}
view.addOnAttachStateChangeListener(attachStateListener);
isAttachStateListenerAdded = true;
}
给Target添加了一个attach监听,当view attach到View上时会触发回调
ViewTarget.java
attachStateListener =
new OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
//恢复请求
resumeMyRequest();
}
@Override
public void onViewDetachedFromWindow(View v) {
//暂停请求
pauseMyRequest();
}
};
void resumeMyRequest() {
Request request = getRequest();
if (request != null && request.isCleared()) {
request.begin();
}
}
void resumeMyRequest() {
Request request = getRequest();
if (request != null && request.isCleared()) {
request.begin();
}
}