Glide框架解析
Glide是android平台中的一个图片加载框架,
可以加载本地图片、网络图片、动态图
Glide的使用
1 | Glide.with(context).load(url).into(imageView); |
可以看出分成三部分:with、load、into
下面我们也分成三部分针对讲解
with
with函数其实是对生命周期的管理
在Glide源码中,可以看到几个with函数,入参类型各不相同
1 | @NonNull |
with函数的入参有
- Context
- Activity
- FragmentActivity
- androidX.Fragment
- android.app.Fragment
- View
可以看到,在with函数中都是调用getRetriever返回RequestManager对象,而调用getRetriever的入参有两个类型 - 1、context
- 2、activity
getRetriever的两种入参类型又是根据上面with函数获取的,
针对fragment、fragmentActiivty、Actiivty获取对应的actiivty
针对context、view,则获取对应的context
再看一下getRetriever函数
getRetriever
1 | @NonNull |
也就是说,getRetriever返回就是一个 RequestManagerRetriever对象
也就是说 with函数最后调用到了RequestManagerRetriever对象的get函数
RequestManagerRetriever
看在Glide.java中的with函数就知道,RequestManagerRetriever中get函数也存在多个1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80@NonNull
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);
}
@NonNull
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));
}
}
@NonNull
public RequestManager get(@NonNull Fragment fragment) {
Preconditions.checkNotNull(fragment.getActivity(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
}
}
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull View view) {
if (Util.isOnBackgroundThread()) {
return get(view.getContext().getApplicationContext());
}
Preconditions.checkNotNull(view);
Preconditions.checkNotNull(view.getContext(),
"Unable to obtain a request manager for a view without a Context");
Activity activity = findActivity(view.getContext());
if (activity == null) {
return get(view.getContext().getApplicationContext());
}
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
return fragment != null ? get(fragment) : get(activity);
}
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
第一个get函数,传入context对象,对context做分发,
其他的get函数,都是判断当前执行线程是否在main线程,如果不是 则都会走到1
return getApplicationManager(context)
在main线程时,会根据传入的参数获取对应的activity,activity为null,则也会执行1
return getApplicationManager(context)
如果activity不为空,则执行1
2
3android.app.FragmentManager fm = activity.getFragmentManager();
return supportFragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
其中android.app.Fragment会略有差异,因为该Fragment为android包下,已被遗弃,但执行逻辑其实大同小异
接下来我们再看supportFragmentGet函数
supportFragmentGet()
跟随Fragment的生命周期1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20@NonNull
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;
}
getApplicationManager
跟随应用的生命周期
1 | @NonNull |
这样的话,就可以看得出调用with函数时,会绑定到一个requestManaget对象,
但是分两种:
- 1、子线程,或出入的Context为ApplicationContext —》 applicationManager —— 跟随应用的生命周期
- 2、main线程 & 非ApplicationContext —-》 requestManager —- 跟随当前Fragment/Activity的生命周期
接着看RequestManager
RequestManager
查看RequestManager的构造函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38public RequestManager(
@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
this(glide, lifecycle, treeNode, new RequestTracker(), glide.getConnectivityMonitorFactory(), context);
}
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
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 {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
两个构造函数,上面的构造函数会调用到下面的构造函数,只有上面的函数才对外暴露。