Glide源码解析

基本用法

使用Glide加载图片非常方便,只要简单三步链式调用即可:

1
2
3
Glide.with(context)
.load("url")
.into(imageView);

with()

Glide.with()方法的所有重载方法都是下面的形式,只是传入的参数类型有区别,这里主要分为两步getRetriever()get()

1
2
3
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}

不管with()方法的参数是啥,其实最终都是通过getRetriever()方法回去到RequestManagerRetriever对象,再通过它获取到RequestManager

1
2
3
4
5
6
7
8
9
10
11
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
//主要的代码
return Glide.get(context).getRequestManagerRetriever();
}

重点主要是在RequestManagerRetriever.get(context)上,该方法会判断传入的context的实际类型,并返回不用的RequestManager,主要有如下几种特殊类型:

  • FragmentActivity
  • Activity
  • ContextWrapper
  • ApplicationContext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper) {
return get(((ContextWrapper) context).getBaseContext());
}
}

return getApplicationManager(context);
}

对于传入的是ApplicationContext或者不是在UI线程执行的情况,Glide只是简单的获取了单例的ApplicationManager对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private RequestManager getApplicationManager(@NonNull Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
// Normally pause/resume is taken care of by the fragment we add to the fragment or
// activity. However, in this case since the manager attached to the application will not
// receive lifecycle events, we must force the manager to start resumed using
// ApplicationLifecycle.

// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}

return applicationManager;
}

如果传入的是FragmentActivityActivity的情况,采取的方案比较类型,首先判断是否在UI线程,如果不在,则走的逻辑和ApplicationContext的情况相同,否则继续调用supportFragmentGet()fragmentGet()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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));
}
}

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()fragmentGet()的实现类似,只是一个用的app包下的Fragment,一个用的Support包下的Fragment,以supportFragmentGet()为例,该方法会创建一个没有View的空Fragment,并将它添加到Activity中,Glide会通过它对Activity的生命周期进行监听,达到根据Activity生命周期进行加载的目的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
}

load()

RequestManager.load()方法会先使用asDrawable()方法创建一个RequestBuilder<Drawable>对象,再调用RequestBuilder对象的load()方法,最终调用loadGeneric()方法设置数据源,并设置数据源以设置的标记为:

1
2
3
4
5
6
7
8
9
10
11
12
13
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}

public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}

private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}

从名字可以看到,RequestBuilder实际上使用的是Builder模式,在此之上常见的error()placeHolder()等方法都是基于此。

into()