添加依赖:
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
Glide加载图片的常见用法:
//this 为 FragmentActivity
//t1为一张图片
Glide.with(this).load(R.drawable.t1).into(iv);
为了方便分析,我们将代码分开写:
RequestManager manager = Glide.with(this);
RequestBuilder requestBuilder = manager.load(R.drawable.t1);
requestBuilder.into(iv);
with方法里传入了this,所以应该是做相关的初始化,这里就不粘贴相关代码。
load方法可以直接进RequestManager中查看,这里贴出相关的方法调用,都在RequestManager中
这里重要的是最终将resourceId传入了RequestBuilder中的model,即代码中添加注释那一行。
public RequestBuilder load (@RawRes @DrawableRes @Nullable Integer resourceId){
return asDrawable().load(resourceId);
}
public RequestBuilder asDrawable () {
return as(Drawable.class);
}
public RequestBuilder < ResourceType > as(
@NonNull Class < ResourceType > resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
public RequestBuilder load (@RawRes @DrawableRes @Nullable Integer resourceId)
{
return loadGeneric(resourceId).apply(signatureOf(ApplicationVersionSignature.obtain(context)));
}
private RequestBuilder loadGeneric (@Nullable Object model){
//这里实际上就是传进来的R.drawable.t1
this.model = model;
isModelSet = true;
return this;
}
into方法简化后的相关代码如下
public ViewTarget into(@NonNull ImageView view) {
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
private > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
BaseRequestOptions> options,
Executor callbackExecutor) {
Request request = buildRequest(target, targetListener, options, callbackExecutor);
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
return target;
}
这里发现比较有价值的应该就是track,直接再去查看RequestManager中的track方法
synchronized void track(@NonNull Target> target, @NonNull Request request) {
targetTracker.track(target);
//这里应该就是要加载图片了
requestTracker.runRequest(request);
}
点进去查看runRequest方法:
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是从哪里来了,可以再往前顺一下,在上面就可以看到request是在into方法中赋值的
Request request = buildRequest(target, targetListener, options, callbackExecutor);
其中一直在buildrequest,这里就不粘贴代码了,最终返回的是SingleRequest,直接再去查看begin方法,简化后的代码如下
public synchronized void begin() {
status = Status.WAITING_FOR_SIZE;
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
}
发现target又不知道是什么了,再往回顺(这是我自己习惯的看代码的方式,有大佬给指导下这样看有问题吗?)
这里的target只有在init方法中被赋值了,而init方法在刚刚未粘贴出来的buildRequest的一系列代码中被调用过,继续往前顺发现target在into方法中传入的,翻看之前的代码
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
继续查看buildImageViewTarget方法,其中也是一系列的组装,这里不粘贴代码,最终
这就是我们要找的target,然后去查看onLoadStarted方法,然而并没有发现这个方法,继续去其父类中寻找
@Override
public void onLoadStarted(@Nullable Drawable placeholder) {
super.onLoadStarted(placeholder);
setResourceInternal(null);
setDrawable(placeholder);
}
这个setDrawable方法让我们看到了希望,点进去看果然:
public void setDrawable(Drawable drawable) {
view.setImageDrawable(drawable);
}