接着上一篇,with方法获取到RequestManager 对象,它实现了LifecycleListener接口,这意味着,页面生命周期的触发会通知到RequestManager 类,但根据上一篇分析,在此之前,它必须先被添加到ActivityFragmentLifecycle的成员变量lifecycleListeners 集合中 ,我们先看它的构造方法。
public class RequestManager implements LifecycleListener,
ModelTypes> {
private final ConnectivityMonitor connectivityMonitor;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private final CopyOnWriteArrayList> defaultRequestListeners;
private final Runnable addSelfToLifecycle = new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
public RequestManager(
@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
this(
glide,
lifecycle,
treeNode,
new RequestTracker(),
glide.getConnectivityMonitorFactory(),
context);
}
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
//网络监听器
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
//后台线程,切到主线程中添加
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
//添加自己到ActivityFragmentLifecycle的集合中
lifecycle.addListener(this);
}
//添加网络监听器
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
//保存到glide的成员列表中
glide.registerRequestManager(this);
}
}
可以看出,ConnectivityMonitor 也实现了LifecycleListener接口,因为它也被添加到lifecycleListeners 集合中,跟随Framgent的生命周期回调。
获取到RequestManager对象后,将调用load方法。
public class RequestManager implements LifecycleListener,
ModelTypes> {
public RequestBuilder load(@Nullable Bitmap bitmap) {
return asDrawable().load(bitmap);
}
public RequestBuilder load(@Nullable Drawable drawable) {
return asDrawable().load(drawable);
}
public RequestBuilder load(@Nullable String string) {
return asDrawable().load(string);
}
//转码后的类型为Bitmap.class
public RequestBuilder asBitmap() {
return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
}
//转码后的类型为Drawable.class
public RequestBuilder asDrawable() {
return as(Drawable.class);
}
//获取RequestBuilder
public RequestBuilder as(
@NonNull Class resourceClass) {
// resourceClass 就是最终要转码的类型
return new RequestBuilder<>(glide, this, resourceClass, context);
}
}
适配不同资源的加载,load有多个重载方法,他们最终都通过as方法来获取一个RequestBuilder对象,后面一连串的链式调用,都将通过这个对象的方法作为入口来执行。和RequestManager 的load方法一样,RequestBuilder的load也有许多重载方法,我们以网络地址加载为例来做分析。
public class RequestBuilder extends BaseRequestOptions>
implements Cloneable,
ModelTypes> {
private Object model;
private boolean isModelSet;
//加载网络地址
public RequestBuilder load(@Nullable String string) {
return loadGeneric(string);
}
//将地址封装成model
private RequestBuilder loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
}
在执行请求前,所有数据源都会被封装成一个model对象,它是Object类型的。
load方法调用完成,便获得的一个RequestBuilder对象,接着通过它调用into方法。
public class RequestBuilder extends BaseRequestOptions>
implements Cloneable,
ModelTypes> {
......
public ViewTarget into(@NonNull ImageView view) {
Util.assertMainThread();
Preconditions.checkNotNull(view);
BaseRequestOptions> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
// 根据裁剪配置options
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:
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
null,
requestOptions,
Executors.mainThreadExecutor());
}
}
会根据我们在ImageView中设置的ScaleType类型,给requestOptions 配置裁剪类型。最后的into重载方法中,将调用buildImageViewTarget根据转码的类型来生成一个 ViewTarget,这个方法定义在GlideContext中。
public class GlideContext extends ContextWrapper {
......
private final ImageViewTargetFactory imageViewTargetFactory;
......
public ViewTarget buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
}
在上一篇分析Glide的初始化时,ImageViewTargetFactory 这个图片显示目标对象工厂,已经在构造方法中创建出来了,同时还创建了GlideContext 对象,将ImageViewTargetFactory 传递给它。
public class ImageViewTargetFactory {
@NonNull
@SuppressWarnings("unchecked")
public ViewTarget buildTarget(@NonNull ImageView view,
@NonNull Class clazz) {
//Bitmap
if (Bitmap.class.equals(clazz)) {
return (ViewTarget) new BitmapImageViewTarget(view);
//是否Drawable或其子类
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (ViewTarget) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException(
"Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
}
ViewTarget的子类有两种,在上面的RequestManager 类中虽然有多个as方法,但最终的转码类型只会有两类,即Bitmap类型或Drawable及其子类类型,我们加载网络地址,这里的ViewTarget将使用DrawableImageViewTarget,它继承ImageViewTarget,持有ImageView对象。
public class DrawableImageViewTarget extends ImageViewTarget {
public DrawableImageViewTarget(ImageView view) {
super(view);
}
@SuppressWarnings({"unused", "deprecation"})
@Deprecated
public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
super(view, waitForLayout);
}
//设置图片
@Override
protected void setResource(@Nullable Drawable resource) {
view.setImageDrawable(resource);
}
}
看到setResource这个方法我们可以猜到,最终图片被显示到ImageView中,将通过它来完成。我们先回到RequestManager 重载的into方法。
public class RequestBuilder extends BaseRequestOptions>
implements Cloneable,
ModelTypes> {
private > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
BaseRequestOptions> options,
Executor callbackExecutor) {
//这里的Target就是DrawableImageViewTarget了
Preconditions.checkNotNull(target);
//是否设置了数据源,也就是url,在load中isModelSet已置为true
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
//Request类是一个接口,他抽象了Glide加载图片请求
Request request = buildRequest(target, targetListener, options, callbackExecutor);
//获取上一次的Request
Request previous = target.getRequest();
// 当前的target里有Request存在
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
//回收刚新建的Request对象
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
//执行当前的Request
previous.begin();
}
//结束
return target;
}
//清除target
requestManager.clear(target);
//Target中设置request
target.setRequest(request);
//执行request
requestManager.track(target, request);
return target;
}
}
Request用来发出加载图片的请求,通过buildRequest来构建,然后将通过RequestManager对象来执行这个请求。我们先看构建过程。
public class RequestBuilder extends BaseRequestOptions>
implements Cloneable,
ModelTypes> {
private Request buildRequest(
Target target,
@Nullable RequestListener targetListener,
BaseRequestOptions> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(
target,
targetListener,
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) {
// 如果配置了错误请求则新建错误请求协调器
ErrorRequestCoordinator errorRequestCoordinator = null;
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
// 构造目标请求
Request mainRequest =
buildThumbnailRequestRecursive(
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
//如果没有配置错误请求则结束,否则继续下面代码构建错误时的备用请求
if (errorRequestCoordinator == null) {
return mainRequest;
}
int errorOverrideWidth = errorBuilder.getOverrideWidth();
int errorOverrideHeight = errorBuilder.getOverrideHeight();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !errorBuilder.isValidOverride()) {
errorOverrideWidth = requestOptions.getOverrideWidth();
errorOverrideHeight = requestOptions.getOverrideHeight();
}
// 错误时的备用请求
Request errorRequest =
errorBuilder.buildRequestRecursive(
target,
targetListener,
errorRequestCoordinator,
errorBuilder.transitionOptions,
errorBuilder.getPriority(),
errorOverrideWidth,
errorOverrideHeight,
errorBuilder,
callbackExecutor);
errorRequestCoordinator.setRequests(mainRequest, errorRequest);
return errorRequestCoordinator;
}
private Request buildThumbnailRequestRecursive(
Target target,
RequestListener targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions> requestOptions,
Executor callbackExecutor) {
if (thumbnailBuilder != null) {
if (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()");
}
// 设置 transitionOptions
TransitionOptions, ? super TranscodeType> thumbTransitionOptions =
thumbnailBuilder.transitionOptions;
if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
thumbTransitionOptions = transitionOptions;
}
//优先级
Priority thumbPriority = thumbnailBuilder.isPrioritySet()
? thumbnailBuilder.getPriority() : getThumbnailPriority(priority);
//图片尺寸
int thumbOverrideWidth = thumbnailBuilder.getOverrideWidth();
int thumbOverrideHeight = thumbnailBuilder.getOverrideHeight();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !thumbnailBuilder.isValidOverride()) {
thumbOverrideWidth = requestOptions.getOverrideWidth();
thumbOverrideHeight = requestOptions.getOverrideHeight();
}
// 缩略图请求协调器
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
// 目标请求
Request fullRequest =
obtainRequest(
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
isThumbnailBuilt = true;
// 缩略图的请求
Request thumbRequest =
thumbnailBuilder.buildRequestRecursive(
target,
targetListener,
coordinator,
thumbTransitionOptions,
thumbPriority,
thumbOverrideWidth,
thumbOverrideHeight,
thumbnailBuilder,
callbackExecutor);
isThumbnailBuilt = false;
coordinator.setRequests(fullRequest, thumbRequest);
return coordinator;
} else if (thumbSizeMultiplier != null) {
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
Request fullRequest =
obtainRequest(
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
BaseRequestOptions> thumbnailOptions =
requestOptions.clone().sizeMultiplier(thumbSizeMultiplier);
Request thumbnailRequest =
obtainRequest(
target,
targetListener,
thumbnailOptions,
coordinator,
transitionOptions,
getThumbnailPriority(priority),
overrideWidth,
overrideHeight,
callbackExecutor);
coordinator.setRequests(fullRequest, thumbnailRequest);
return coordinator;
} else {
// 没有缩略图时,构造请求
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);
}
}
构建目标Request请求的代码比较长,如果我们配置了缩略图要求,它将构建缩略图请求,并和目标请求一起放入到协调器中。ThumbnailRequestCoordinator 请求协调器,可以用来协调各请求的顺序。
我们只分析目标请求流程,也就是没有设置缩略图的情况。由obtain静态方法可以看到,最终获得的目标Request对象就是SingleRequest,它封装了图片请求需要的各个成员。
public final class SingleRequest implements Request,
SizeReadyCallback,
ResourceCallback,
FactoryPools.Poolable {
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();
//创建SingleRequest对象
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;
}
//赋值成员变量
private synchronized void init(
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) {
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");
}
}
}
目标Request已经构建完成,再回到requestManager.track(target, request)这行代码,看Request如何被发出去的。它通过RequestManager来调用。
public class RequestManager implements LifecycleListener,
ModelTypes> {
//请求追踪器
private final RequestTracker requestTracker;
public RequestManager(
@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
this(
glide,
lifecycle,
treeNode,
new RequestTracker(),//创建请求追踪器
glide.getConnectivityMonitorFactory(),
context);
}
synchronized void track(@NonNull Target> target, @NonNull Request request) {
targetTracker.track(target);
// 开始请求
requestTracker.runRequest(request);
}
}
任务被移交给了RequestTracker请求追踪器进行追踪,这个对象RequestManager在构造时创建的。
public class RequestTracker {
private final Set requests =
Collections.newSetFromMap(new WeakHashMap());
private final List pendingRequests = new ArrayList<>();
private boolean isPaused;
//执行请求任务
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);
}
}
如果任务此时被暂停了,那么将清理掉某些资源,但这个Request 还可以通过begin()方法来重新发出,所以被保存到pendingRequests待处理
列表中。
上面说过,所有图片请求相关的成员都被封装到Request(SingleRequest )对象中,它将指定Target去加载自己的资源。
public final class SingleRequest implements Request,
SizeReadyCallback,
ResourceCallback,
FactoryPools.Poolable {
public synchronized void begin() {
assertNotCallingCallbacks();
stateVerifier.throwIfRecycled();
startTime = LogTime.getLogTime();
//即地址为null
if (model == null) {
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
width = overrideWidth;
height = overrideHeight;
}
int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
//加载出错处理
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;
// 如果指定了宽高,直接回调 onSizeReady
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
// 根据 target 的宽高来加载图片的宽高
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));
}
}
public synchronized void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
if (IS_VERBOSE_LOGGABLE) {
logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;
float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
if (IS_VERBOSE_LOGGABLE) {
logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
}
//加载图片并返回状态
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);
if (status != Status.RUNNING) {
loadStatus = null;
}
if (IS_VERBOSE_LOGGABLE) {
logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
}
}
加载分两种情况,如果指定了一个固定的宽高,就会直接执行onSizeReady()方法。如果没指定的话,调用target.getSize()方法。这个target.getSize()方法,它会根据ImageView布局设置的宽高,算出图片应该显示的宽高。计算完之后,它也会调用onSizeReady()方法。
但请求加载流程还不是在这个类中执行的,它把这个任务交给了Engine对象来处理,这个对象是在GlideBuilder的build方法中创建的,我们前面分析过,在build方法中还创建了几个缓存池和以及复用池,这些池子都封装到了Engine对象中。并且在随后的Glide构造方法中构建GlideContext对象时,将其保存到这个上下文中。
public class Engine implements EngineJobListener,
MemoryCache.ResourceRemovedListener,
EngineResource.ResourceListener {
public synchronized LoadStatus load(
GlideContext glideContext,
Object model,
Key signature,
int width,
int height,
Class> resourceClass,
Class transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map, Transformation>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
Options options,
boolean isMemoryCacheable,
boolean useUnlimitedSourceExecutorPool,
boolean useAnimationPool,
boolean onlyRetrieveFromCache,
ResourceCallback cb,
Executor callbackExecutor) {
long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;
// 创建资源索引 KEY
EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
resourceClass, transcodeClass, options);
//从缓存中取
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;
}
//从缓存中获取
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;
}
// 获取已经存在的加载任务 ,onlyRetrieveFromCache 参数表示是否只加载缓存中的数据
EngineJob> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
// 添加 SingleRequest 回调对象
current.addCallback(cb, callbackExecutor);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current);
}
// 构造 EngineJob 对象,用于启动解码任务
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.put(key, engineJob);
// 添加 SingleRequest 回调对象
engineJob.addCallback(cb, callbackExecutor);
// 执行解码任务
engineJob.start(decodeJob);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Started new load", startTime, key);
}
return new LoadStatus(cb, engineJob);
}
}
既然Engine 封装了许多缓存池,那么做网络请求前,必然先看缓存有没有。buildKey方法将几个参数封装成EngineKey ,根据这个Key 来获取内存缓存数据,如果存在,则直接回调成功,如果不存在,则新建EngineJob 对象和DecodeJob解码器,DecodeJob实现了Runnable,通过EngineJob 对象调用start来启动。
缓存的获取这里先不分析,我们分析首次加载,即没有缓存的情况。那么,紧接着的工作又传递给了EngineJob 对象,它会通过线程池来开启DecodeJob这个Runnable。
class EngineJob implements DecodeJob.Callback,
Poolable {
//通过线程池启动图片加载任务
public synchronized void start(DecodeJob decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
executor.execute(decodeJob);
}
}
很显然,GlideExecutor 是Glide自定义的Executor,它内部实现了线程池。因此,我们直接看DecodeJob的run方法。
class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable>,
Poolable {
//加载辅助类
private final DecodeHelper decodeHelper = new DecodeHelper<>();
DecodeJob init(
GlideContext glideContext,
Object model,
EngineKey loadKey,
Key signature,
int width,
int height,
Class> resourceClass,
Class transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map, Transformation>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
boolean onlyRetrieveFromCache,
Options options,
Callback callback,
int order) {
decodeHelper.init(
glideContext,
model,
signature,
width,
height,
diskCacheStrategy,
resourceClass,
transcodeClass,
priority,
options,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
diskCacheProvider);
this.glideContext = glideContext;
this.signature = signature;
this.priority = priority;
this.loadKey = loadKey;
this.width = width;
this.height = height;
this.diskCacheStrategy = diskCacheStrategy;
this.onlyRetrieveFromCache = onlyRetrieveFromCache;
this.options = options;
this.callback = callback;
this.order = order;
this.runReason = RunReason.INITIALIZE;//初始化RunReason为INITIALIZE
this.model = model;
return this;
}
public void run() {
GlideTrace.beginSectionFormat("DecodeJob#run(model=%s)", model);
DataFetcher> localFetcher = currentFetcher;
try {
if (isCancelled) {
notifyFailed();
return;
}
//进入runWrapped
runWrapped();
} catch (CallbackException e) {
throw e;
} catch (Throwable t) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "DecodeJob threw unexpectedly"
+ ", isCancelled: " + isCancelled
+ ", stage: " + stage, t);
}
if (stage != Stage.ENCODE) {
throwables.add(t);
notifyFailed();
}
if (!isCancelled) {
throw t;
}
throw t;
} finally {
if (localFetcher != null) {
localFetcher.cleanup();
}
GlideTrace.endSection();
}
}
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
stage = getNextStage(Stage.INITIALIZE);
currentGenerator = getNextGenerator();
runGenerators();
break;
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
case DECODE_DATA:
decodeFromRetrievedData();
break;
default:
throw new IllegalStateException("Unrecognized run reason: " + runReason);
}
}
//获取不同类型加载器
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);
}
}
//根据不同加载器获取图片
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
while (!isCancelled && currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
if (stage == Stage.SOURCE) {
reschedule();
return;
}
}
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
}
}
在DecodeJob被构造和初始化时,RunReason设置为INITIALIZE,也就是说,runWrapped进入了INITIALIZE这个case,如代码所示,有处理过的缓存资源加载器、原始图片资源缓存加载器和远程图片资源加载器3种不同类型的加载器,会根据当前的状态决定使用哪一个,由于是首次加载,因此,将获取到远程图片资源加载器,即SourceGenerator这个对象。
runGenerators方法内是一个while递归循环,它通过加载器的startNext方法来执行加载的任务,开启成功结束循环,不再寻找新的加载器。
class SourceGenerator implements DataFetcherGenerator,
DataFetcher.DataCallback
DecodeHelper是在Engine中构建的,使用getLoadData获取到ModelLoader的列表。
final class DecodeHelper {
//获取List>
List> getLoadData() {
if (!isLoadDataSet) {
isLoadDataSet = true;
loadData.clear();
List> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
for (int i = 0, size = modelLoaders.size(); i < size; i++) {
//这个ModelLoader为HttpGlideUrlLoader
ModelLoader
这里获取到ModelLoader为HttpGlideUrlLoader类型的,通过buildLoadData构建一个ModelLoader.LoadData对象。
public class HttpGlideUrlLoader implements ModelLoader {
public LoadData buildLoadData(@NonNull GlideUrl model, int width, int height,
@NonNull Options options) {
GlideUrl url = model;
if (modelCache != null) {
url = modelCache.get(model, 0, 0);
if (url == null) {
modelCache.put(model, 0, 0, model);
url = model;
}
}
int timeout = options.get(TIMEOUT);
//构建HttpUrlFetcher将它传递给LoadData
return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
}
}
因此,上面loadData.fetcher.loadData代码就是在HttpUrlFetcher中执行的。
public class HttpUrlFetcher implements DataFetcher {
@Override
public void loadData(@NonNull Priority priority,
@NonNull DataCallback super InputStream> callback) {
long startTime = LogTime.getLogTime();
// 调用 loadDataWithRedirects 方法执行网络请求
try {
InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
//将输入流回调给DataCallback
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 headers) throws IOException {
if (redirects >= MAXIMUM_REDIRECTS) {
throw new HttpException("Too many (> " + MAXIMUM_REDIRECTS + ") redirects!");
} else {
try {
if (lastUrl != null && url.toURI().equals(lastUrl.toURI())) {
throw new HttpException("In re-direct loop");
}
} catch (URISyntaxException e) {
}
}
//根据url构建Connection
urlConnection = connectionFactory.build(url);
for (Map.Entry headerEntry : headers.entrySet()) {
urlConnection.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
}
urlConnection.setConnectTimeout(timeout);
urlConnection.setReadTimeout(timeout);
urlConnection.setUseCaches(false);
urlConnection.setDoInput(true);
urlConnection.setInstanceFollowRedirects(false);
//请求下载
urlConnection.connect();
//先将输入流保存
stream = urlConnection.getInputStream();
//如果没有突然被取消
if (isCancelled) {
return null;
}
//状态码
final int statusCode = urlConnection.getResponseCode();
//状态码为200,将输入流返回
if (isHttpOk(statusCode)) {
return getStreamForSuccessfulRequest(urlConnection);
} else if (isHttpRedirect(statusCode)) {
String redirectUrlString = urlConnection.getHeaderField("Location");
if (TextUtils.isEmpty(redirectUrlString)) {
throw new HttpException("Received empty or null redirect url");
}
URL redirectUrl = new URL(url, redirectUrlString);
cleanup();
return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
} else if (statusCode == INVALID_STATUS_CODE) {
throw new HttpException(statusCode);
} else {
throw new HttpException(urlConnection.getResponseMessage(), statusCode);
}
}
//获取输入流
private InputStream getStreamForSuccessfulRequest(HttpURLConnection urlConnection)
throws IOException {
if (TextUtils.isEmpty(urlConnection.getContentEncoding())) {
int contentLength = urlConnection.getContentLength();
stream = ContentLengthInputStream.obtain(urlConnection.getInputStream(), contentLength);
} else {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Got non empty content encoding: " + urlConnection.getContentEncoding());
}
stream = urlConnection.getInputStream();
}
return stream;
}
//状态码为200
private static boolean isHttpOk(int statusCode) {
return statusCode / 100 == 2;
}
}
分析到这,总算看到网络请求的调用了。如果状态为200,那么将获取得数据输入流,回调给DataCallback接口,它是从loadData方法传递进来的,再回头loadData的调用知道,它其实就是SourceGenerator对象。
class SourceGenerator implements DataFetcherGenerator,
DataFetcher.DataCallback
Glide认为远程网络图片获取是昂贵的,所以默认情况下网络图片会缓存原图,但本地图片,包括drawable/assets等不会缓存原图。
有没有缓存,最终都会调用到onDataFetcherReady这个方法。与没有缓存相比,有缓存流程上的区别是,会将数据流缓存到磁盘中,然后开一个新的线程,再通过另一个缓存加载器处理,并获取数据流。以上说过,默认是有缓存原图的,因此,我们先分析缓存的调用流程。
在这里提一下,整个流程的调用就类似一个命令下发,这个命令会一层层往下传递,传给到最后一棒的对象去取得数据,再沿着原来的路线,将完成的数据,一层层往回传。这一点务必记住,后面的流程都是在一边处理数据,一边向之前的对象传递,直至传给SingleRequest这个对象里的Target成员,来显示图片。
因此,这里就开始了往前的传递,调用reschedule的对象为DecodeJob。
class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable>,
Poolable {
@Override
public void reschedule() {
//RunReason被置为SWITCH_TO_SOURCE_SERVICE
runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
//回调给EngineJob
callback.reschedule(this);
}
RunReason被置为SWITCH_TO_SOURCE_SERVICE。紧接着再次往回通知EngineJob对象。
class EngineJob implements DecodeJob.Callback,
Poolable {
@Override
public void reschedule(DecodeJob> job) {
getActiveSourceExecutor().execute(job);
}
}
重新开启线程,执行DecodeJob这个任务。这回直接执行runGenerators方法,再次调用SourceGenerator的startNext方法,此时缓存就不为null了。
class SourceGenerator implements DataFetcherGenerator,
DataFetcher.DataCallback
dataToCache 将不再是 null ,所以会将数据缓存到本地硬盘,并启动另一个加载器DataCacheGenerator,这个加载器正是用来加载缓存在本地的图片的。它赋值给了成员变量sourceCacheGenerator ,随后执行其startNext方法。
DataCacheGenerator和ResourceCacheGenerator这两个加载器跟SourceGenerator类似,只不过根据不同情形的图片进行加载:
- DataCacheGenerator:用于加载原始图片。
- ResourceCacheGenerator:用于加载处理过的图片。
- SourceGenerator:用于加载网络图片。
因此,数据从缓存中加载成功,同样回传给DataCacheGenerator的 onDataReady方法。
class DataCacheGenerator implements DataFetcherGenerator,
DataFetcher.DataCallback {
public void onDataReady(Object data) {
cb.onDataFetcherReady(sourceKey, data, loadData.fetcher, DataSource.DATA_DISK_CACHE, sourceKey);
}
}
前面我们提到过,有没有缓存,最终都会调用DecodeJob的onDataFetcherReady方法,因为它是用来解码的。
class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable>,
Poolable {
@Override
public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher> fetcher,
DataSource dataSource, Key attemptedKey) {
this.currentSourceKey = sourceKey;
this.currentData = data;
this.currentFetcher = fetcher;
this.currentDataSource = dataSource;
this.currentAttemptingKey = attemptedKey;
if (Thread.currentThread() != currentThread) {
runReason = RunReason.DECODE_DATA;
callback.reschedule(this);
} else {
GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
try {
//解码数据
decodeFromRetrievedData();
} finally {
GlideTrace.endSection();
}
}
//解码获取Resource
private void decodeFromRetrievedData() {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Retrieved data", startFetchTime,
"data: " + currentData
+ ", cache key: " + currentSourceKey
+ ", fetcher: " + currentFetcher);
}
Resource resource = null;
try {
//解码得到LazyBitmapDrawableResource
resource = decodeFromData(currentFetcher, currentData, currentDataSource);
} catch (GlideException e) {
e.setLoggingDetails(currentAttemptingKey, currentDataSource);
throwables.add(e);
}
//进行编码输出
if (resource != null) {
notifyEncodeAndRelease(resource, currentDataSource);
} else {
runGenerators();
}
}
private Resource decodeFromData(DataFetcher> fetcher, Data data,
DataSource dataSource) throws GlideException {
try {
if (data == null) {
return null;
}
long startTime = LogTime.getLogTime();
//从DecodeHelper中获取LoadPath对象
Resource result = decodeFromFetcher(data, dataSource);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Decoded result " + result, startTime);
}
return result;
} finally {
fetcher.cleanup();
}
}
private Resource decodeFromFetcher(Data data, DataSource dataSource)
throws GlideException {
LoadPath path = decodeHelper.getLoadPath((Class) data.getClass());
return runLoadPath(data, dataSource, path);
}
private Resource runLoadPath(Data data, DataSource dataSource,
LoadPath path) throws GlideException {
Options options = getOptionsWithHardwareConfig(dataSource);
DataRewinder rewinder = glideContext.getRegistry().getRewinder(data);
try {
//使用LoadPath进行解码
return path.load(
rewinder, options, width, height, new DecodeCallback(dataSource));
} finally {
rewinder.cleanup();
}
}
}
解码的流程最终是通过LoadPath这个对象来进行处理的。它是根据传入的处理数据,来返回特定的数据解码处理器对象。
public class LoadPath {
public Resource load(DataRewinder rewinder, @NonNull Options options, int width,
int height, DecodePath.DecodeCallback decodeCallback) throws GlideException {
List throwables = Preconditions.checkNotNull(listPool.acquire());
try {
return loadWithExceptionList(rewinder, options, width, height, decodeCallback, throwables);
} finally {
listPool.release(throwables);
}
}
private Resource loadWithExceptionList(DataRewinder rewinder,
@NonNull Options options,
int width, int height, DecodePath.DecodeCallback decodeCallback,
List exceptions) throws GlideException {
Resource result = null;
//遍历从列表获取DecodePath进行解码
for (int i = 0, size = decodePaths.size(); i < size; i++) {
DecodePath path = decodePaths.get(i);
try {
//开始解码
result = path.decode(rewinder, width, height, options, decodeCallback);
} catch (GlideException e) {
exceptions.add(e);
}
if (result != null) {
break;
}
}
if (result == null) {
throw new GlideException(failureMessage, new ArrayList<>(exceptions));
}
return result;
}
}
DecodePath类还并不是最终的解码器,它只是封装解码和转码的工具,它本身不做解码转码的具体操作。
public class DecodePath {
//转码器
private final ResourceTranscoder transcoder;
public Resource decode(DataRewinder rewinder, int width, int height,
@NonNull Options options, DecodeCallback callback) throws GlideException {
// 返回的可能是 BitmapResource 对象,看具体类型
Resource decoded = decodeResource(rewinder, width, height, options);
// 回调 DecodeJob 的 onResourceDecoded 方法,返回需要转码的类型
Resource transformed = callback.onResourceDecoded(decoded);
//转码 BitmapResource,返回 LazyBitmapDrawableResource
return transcoder.transcode(transformed, options);
}
private Resource decodeResourceWithList(DataRewinder rewinder, int width,
int height, @NonNull Options options, List exceptions) throws GlideException {
Resource result = null;
//遍历获取StreamBitmapDecoder
for (int i = 0, size = decoders.size(); i < size; i++) {
ResourceDecoder decoder = decoders.get(i);
try {
DataType data = rewinder.rewindAndGet();
if (decoder.handles(data, options)) {
data = rewinder.rewindAndGet();
//解码成Drawable
result = decoder.decode(data, width, height, options);
}
} catch (IOException | RuntimeException | OutOfMemoryError e) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Failed to decode data for " + decoder, e);
}
exceptions.add(e);
}
if (result != null) {
break;
}
}
if (result == null) {
throw new GlideException(failureMessage, new ArrayList<>(exceptions));
}
return result;
}
}
这里需要的是 Drawable 类型,所以,decodeResource方法最终会通过 StreamBitmapDecoder将数据流解码成一个 BitmapResource 对象。再通过ResourceTranscoder转码器,它是BitmapDrawableTranscoder类型的,转码为LazyBitmapDrawableResource对象。
public class BitmapDrawableTranscoder implements ResourceTranscoder {
private final Resources resources;
@SuppressWarnings("unused")
public BitmapDrawableTranscoder(@NonNull Context context) {
this(context.getResources());
}
@Deprecated
public BitmapDrawableTranscoder(
@NonNull Resources resources, @SuppressWarnings("unused") BitmapPool bitmapPool) {
this(resources);
}
public BitmapDrawableTranscoder(@NonNull Resources resources) {
this.resources = Preconditions.checkNotNull(resources);
}
//转码
@Override
public Resource transcode(@NonNull Resource toTranscode,
@NonNull Options options) {
return LazyBitmapDrawableResource.obtain(resources, toTranscode);
}
}
public final class LazyBitmapDrawableResource implements Resource,
Initializable {
//获取LazyBitmapDrawableResource对象
public static Resource obtain(
@NonNull Resources resources, @Nullable Resource bitmapResource) {
if (bitmapResource == null) {
return null;
}
return new LazyBitmapDrawableResource(resources, bitmapResource);
}
//获取BitmapDrawable
@Override
public BitmapDrawable get() {
return new BitmapDrawable(resources, bitmapResource.get());
}
}
这里注意到get方法返回了BitmapDrawable对象,它就是最终用来显示到ImageView上的类型。现在解码和转码工作已经完成了。所以,数据继续往回传递通知上层,将获取到的结果进行展示。
因此,回到DecodeJob类的decodeFromRetrievedData方法内部,调用notifyEncodeAndRelease 继续往下执行。
class DecodeJob implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable>,
Poolable {
private void notifyEncodeAndRelease(Resource resource, DataSource dataSource) {
if (resource instanceof Initializable) {
((Initializable) resource).initialize();
}
//将资源锁定
Resource result = resource;
LockedResource lockedResource = null;
if (deferredEncodeManager.hasResourceToEncode()) {
lockedResource = LockedResource.obtain(resource);
result = lockedResource;
}
//通知上层任务完成
notifyComplete(result, dataSource);
stage = Stage.ENCODE;
try {
if (deferredEncodeManager.hasResourceToEncode()) {
deferredEncodeManager.encode(diskCacheProvider, options);
}
} finally {
if (lockedResource != null) {
lockedResource.unlock();
}
}
onEncodeComplete();
}
private void notifyComplete(Resource resource, DataSource dataSource) {
setNotifiedOrThrow();
//回调给EngineJob
callback.onResourceReady(resource, dataSource);
}
}
LazyBitmapDrawableResource数据继续往回传给EngineJob类。它还会继续往上传给SingleRequest类。
class EngineJob implements DecodeJob.Callback,
Poolable {
//这是LazyBitmapDrawableResource
private Resource> resource;
@Override
public void onResourceReady(Resource resource, DataSource dataSource) {
//保存数据
synchronized (this) {
this.resource = resource;
this.dataSource = dataSource;
}
notifyCallbacksOfResult();
}
@Synthetic
void notifyCallbacksOfResult() {
ResourceCallbacksAndExecutors copy;
Key localKey;
EngineResource> localResource;
synchronized (this) {
stateVerifier.throwIfRecycled();
if (isCancelled) {
resource.recycle();
release();
return;
} else if (cbs.isEmpty()) {
throw new IllegalStateException("Received a resource without any callbacks to notify");
} else if (hasResource) {
throw new IllegalStateException("Already have resource");
}
//构建EngineResource
engineResource = engineResourceFactory.build(resource, isCacheable);
hasResource = true;
copy = cbs.copy();
incrementPendingCallbacks(copy.size() + 1);
localKey = key;
localResource = engineResource;
}
listener.onEngineJobComplete(this, localKey, localResource);
//通过子线程回调
for (final ResourceCallbackAndExecutor entry : copy) {
entry.executor.execute(new CallResourceReady(entry.cb));
}
decrementPendingCallbacks();
}
private class CallResourceReady implements Runnable {
private final ResourceCallback cb;
CallResourceReady(ResourceCallback cb) {
this.cb = cb;
}
@Override
public void run() {
synchronized (EngineJob.this) {
if (cbs.contains(cb)) {
engineResource.acquire();
//调用callCallbackOnResourceReady传递给SingleRequest
callCallbackOnResourceReady(cb);
removeCallback(cb);
}
decrementPendingCallbacks();
}
}
}
@SuppressWarnings("WeakerAccess")
@Synthetic
synchronized void callCallbackOnResourceReady(ResourceCallback cb) {
try {
//调用SingleRequest的onResourceReady方法
cb.onResourceReady(engineResource, dataSource);
} catch (Throwable t) {
throw new CallbackException(t);
}
}
}
EngineJob构建了一个EngineResource,将LazyBitmapDrawableResource封装在它的内部,然后开启线程,将数据传递给了SingleRequest类。
public final class SingleRequest implements Request,
SizeReadyCallback,
ResourceCallback,
FactoryPools.Poolable {
@Override
public synchronized void onResourceReady(Resource> resource, DataSource dataSource) {
stateVerifier.throwIfRecycled();
loadStatus = null;
if (resource == null) {
GlideException exception = new GlideException("Expected to receive a Resource with an "
+ "object of " + transcodeClass + " inside, but instead got null.");
onLoadFailed(exception);
return;
}
从EngineResource中获取BitmapDrawable对象
Object received = resource.get();
if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
releaseResource(resource);
GlideException exception = new GlideException("Expected to receive an object of "
+ transcodeClass + " but instead" + " got "
+ (received != null ? received.getClass() : "") + "{" + received + "} inside" + " "
+ "Resource{" + resource + "}."
+ (received != null ? "" : " " + "To indicate failure return a null Resource "
+ "object, rather than a Resource object containing null data."));
onLoadFailed(exception);
return;
}
if (!canSetResource()) {
releaseResource(resource);
status = Status.COMPLETE;
return;
}
//通知Target显示图片
onResourceReady((Resource) resource, (R) received, dataSource);
}
private synchronized void onResourceReady(Resource resource, R result, DataSource dataSource) {
boolean isFirstResource = isFirstReadyResource();
status = Status.COMPLETE;
this.resource = resource;
if (glideContext.getLogLevel() <= Log.DEBUG) {
Log.d(GLIDE_TAG, "Finished loading " + result.getClass().getSimpleName() + " from "
+ dataSource + " for " + model + " with size [" + width + "x" + height + "] in "
+ LogTime.getElapsedMillis(startTime) + " ms");
}
isCallingCallbacks = true;
try {
boolean anyListenerHandledUpdatingTarget = false;
if (requestListeners != null) {
for (RequestListener listener : requestListeners) {
anyListenerHandledUpdatingTarget |=
listener.onResourceReady(result, model, target, dataSource, isFirstResource);
}
}
anyListenerHandledUpdatingTarget |=
targetListener != null
&& targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);
if (!anyListenerHandledUpdatingTarget) {
Transition super R> animation =
animationFactory.build(dataSource, isFirstResource);
//显示资源
target.onResourceReady(result, animation);
}
} finally {
isCallingCallbacks = false;
}
notifyLoadSuccess();
}
}
注意代码中的resource.get()调用,这个resource是传递过来的EngineResource,上面说过,它已经持有了LazyBitmapDrawableResource,这个get方法,便会调用LazyBitmapDrawableResource的get方法获取到BitmapDrawable对象,紧接着调用onResourceReady方法让Target去展示图片。
在最前面分析说过,这个Target是ImageViewTarget的子类,BitmapImageViewTarget。
public abstract class ImageViewTarget extends ViewTarget
implements Transition.ViewAdapter {
@Override
public void onResourceReady(@NonNull Z resource, @Nullable Transition super Z> transition) {
if (transition == null || !transition.transition(resource, this)) {
//设置资源
setResourceInternal(resource);
} else {
maybeUpdateAnimatable(resource);
}
}
private void setResourceInternal(@Nullable Z resource) {
//调用子类方法
setResource(resource);
maybeUpdateAnimatable(resource);
}
protected abstract void setResource(@Nullable Z resource);
}
public class DrawableImageViewTarget extends ImageViewTarget {
public DrawableImageViewTarget(ImageView view) {
super(view);
}
@SuppressWarnings({"unused", "deprecation"})
@Deprecated
public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
super(view, waitForLayout);
}
//显示图片
@Override
protected void setResource(@Nullable Drawable resource) {
view.setImageDrawable(resource);
}
}
到此,Glide整个图片加载流程分析完毕。其中的into流程是最复杂的,因为Glide做了大量的缓存处理和对象复用。但整个基本调用流程是:下发一个Request后,通过网络请求获得数据,进行解码和转码,再沿路返回到Request类中,让Target去做图片展示。