一直想写这篇文章,总怕写得不好。第一步,就先简单分析下Glide的代码流程吧。首先,我们看看,是怎样使用Glide加载图片的。
Glide.with(this)
.load("https://goo.gl/images/r9XuWC")
.into(iv);
可以看到,使用非常简单。那就简单分析下,每一步做了些什么事情。我打算分析下三个比较重要的方法。
Glide.with()
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
可以看到,不管我们传入Activity,还是Fragment,最后都会通过RequestManagerRetriever返回一个RequestManager对象。那么RequestManagerRetriever,RequestManager是干什么的?
RequestManagerRetriever:用来创建新的RequestManager,或者从Activity,Fragment拿到已经存在的RequestManager。
RequestManager:Glide用来管理,开启Request的。
好了,知道了这两个的作用之后,我们看下这个with方法的内部实现。
getRetriever(activity).get(activity)
我们着重看一下RequestManagerRetriever的get方法:
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
前面的判断逻辑我们跳过,着重分析下supportFragmentGet(activity, fm, /parentHint=/ null, isActivityVisible(activity))这句。
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
这个方法比较重要。总共做了三件事情。
- 创建SupportRequestManagerFragment;
- 创建RequestManager;
- 将SupportRequestManagerFragment与RequestManager绑定。
那么SupportRequestManagerFragment是干啥的呢?SupportRequestManagerFragment是一个无界面的Fragment,用来开启,停止,管理fragment,或者当前fragment的父Activity中Glide图片加载请求的。
在SupportRequestManagerFragment内部,可以看到一个ActivityFragmentLifecycle类型的变量lifecycle。
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
在SupportRequestManagerFragment的生命周期中回调lifecycle的生命周期方法。
在创建RequestManager时,我们将SupportRequestManagerFragment内部的lifecycle传递进去。这样就将RequestManager的生命周期与Fragment,或者Activity的生命周期巧妙地结合起来。
@Override
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public void onStop() {
pauseRequests();
targetTracker.onStop();
}
@Override
public void onDestroy() {
targetTracker.onDestroy();
for (Target<?> target : targetTracker.getAll()) {
clear(target);
}
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
mainHandler.removeCallbacks(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
这样,在RequestManager的生命周期中,我们可以开启,暂停,停止图片加载请求。这也是Glide设计比较巧妙的地方。
RequestManager.load()
可以看到,重载的load方法很多,但最后都是调用loadGeneric方法。
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
可以看到,就是进行一些数据简单的设置。
RequestBuilder.into()
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
@NonNull RequestOptions options) {
Util.assertMainThread();
Preconditions.checkNotNull(target);
//(1)判断数据是否设置,就是我们load方法所做的事情
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
options = options.autoClone();
Request request = buildRequest(target, targetListener, options);
Request previous = target.getRequest();
//(2)中间这部分,就是一些优化操作,熟悉主流程的话可以忽略。
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
previous.begin();
}
return target;
}
requestManager.clear(target);
//(3)最后就是将Request请求与我们显示图片的目标Target进行绑定。
target.setRequest(request);
requestManager.track(target, request);
return target;
}
into方法里面有个比较重要的一句,requestManager.track(target, request)。我们进去看一下,里面做了什么事情。
void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
在TargetTracker内部,有一个弱引用的Target集合。当我们调用TargetTracker.track(Target),就将当前Target添加到Set集合中来。加进来干什么呢?就是在Target的生命周期回调中,执行Target的生命周期回调。所以说,targetTracker.track(target)就是对Target进行生命周期追踪管理的。
下面,我们看看 requestTracker.runRequest(request)这句代码做了什么事情。
public void runRequest(@NonNull Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Paused, delaying request");
}
pendingRequests.add(request);
}
}
在这个RequestTracker里面,有两个Request的集合。
private final Set<Request> requests =
Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
//未完成的Request集合
private final List<Request> pendingRequests = new ArrayList<>();