Glide源码解析05-onLoadComplete
在Glide源码解析03中我们以及看到Glide调用了EngineRunnable#onLoadFailed或者EngineRunnable#onLoadComplete来调用失败或成功的结果。
这里我们来详细看下onLoadComplete,onLoadFailed也是同样的逻辑。
if (resource == null) {
onLoadFailed(exception);
} else {
onLoadComplete(resource);
}
5.0 Handler.obtainMessage(MSG_COMPLETE)
在onLoadComplete中调用了EngineRunnableManager#onResourceReady(),其内部调用Handler发送了MSG_COMPLETE的消息。
public void onResourceReady(final Resource<?> resource) {
this.resource = resource;
MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}
5.1 Handler.handleMessage
在handleMessage中,调用了EngineJob#handleResultOnMainThread()
public boolean handleMessage(Message message) {
if (MSG_COMPLETE == message.what || MSG_EXCEPTION == message.what) {
EngineJob job = (EngineJob) message.obj;
if (MSG_COMPLETE == message.what) {
job.handleResultOnMainThread();
} else {
job.handleExceptionOnMainThread();
}
return true;
}
return false;
}
5.2 EngineJob#handleResultOnMainThread
在这里,会去遍历ResourceCallback集合,并调用其onResourceReady(),这里的cb是GenericRequest对象。
private void handleResultOnMainThread() {
//...
for (ResourceCallback cb : cbs) {
if (!isInIgnoredCallbacks(cb)) {
engineResource.acquire();
cb.onResourceReady(engineResource);
}
}
//...
}
5.3 GenericRequest#onResourceReady ####
在这里会去调用target#onResourceReady(),target可以是ImageViewTarget的子类GlideDrawableImageViewTarget、DrawableImageViewTarget、BitmapImageViewTarget。
具体构建的地方在Glide电泳into方法时,使用ImageViewTargetFactory.buildTarget创建的target对象。
public void onResourceReady(Resource<?> resource) {
//...
onResourceReady(resource, (R) received);
}
private void onResourceReady(Resource<?> resource, R result) {
boolean isFirstResource = isFirstReadyResource();
status = Status.COMPLETE;
this.resource = resource;
if (requestListener == null || !requestListener.onResourceReady(result, model, target, loadedFromMemoryCache,
isFirstResource)) {
GlideAnimation<R> animation = animationFactory.build(loadedFromMemoryCache, isFirstResource);
target.onResourceReady(result, animation);
}
notifyLoadSuccess();
//...
}
5.4 ImageViewTarget#onResourceReady
ImageViewTarget的子类,调用onResourceReady时,最终都会调用setResource(),比如DrawableImageViewTarget
public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
public DrawableImageViewTarget(ImageView view) {
super(view); //父类调用了setResource方法
}
@Override
protected void setResource(Drawable resource) {
view.setImageDrawable(resource);
}
}
至此,图片加载成功。
PS:cb.onResourceReady
在5.2中,调用的cb.onResourceReady,cb为什么是GenericRequest对象对象呢? 这要看调用GenericRequest#onSizeReady()的时候
//GenericRequest#onSizeReady()
public void onSizeReady(int width, int height) {
//...
loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
priority, isMemoryCacheable, diskCacheStrategy, this);
loadedFromMemoryCache = resource != null;
//...
}
//Engine#load()
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
//...
EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
//...
EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
jobs.put(key, engineJob);
//将cb添加到EngineJob中,而cb就是GenericRequest调用engine.load时传入的this参数。
engineJob.addCallback(cb);
engineJob.start(runnable);
return new LoadStatus(cb, engineJob);
}
更多
Glide源码解析01-with
Glide源码解析02-load
Glide源码解析03-into
Glide源码解析04-decode
Glide源码解析05-onLoadComplete
Glide源码解析06-Glide流程图