声明:我目前分析的源码是最新的Glide源码:4.12.0版本

1
2
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

1. Glide简介

Glide是一个支持拉取,解码和展示视频快照,图片,和GIF动画的框架,正如它的名字翻译一样:滑翔。让用户加载任何形式的图片列表尽可能地变得更快、更平滑。

Glide 使用简明灵活的流式语法API,允许你在大部分情况下一行代码搞定需求:

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

默认情况下,Glide使用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。

2. 性能

Glide 充分考虑了Android图片加载性能的两个关键方面:

  • 图片解码速度

  • 解码图片带来的资源压力

为了让用户拥有良好的App使用体验,图片不仅要快速加载,而且还不能因为过多的主线程I/O或频繁的垃圾回收导致页面的闪烁和抖动现象。Glide使用了多个步骤来确保在Android上加载图片尽可能的快速和平滑:

  • 自动、智能地下采样(downsampling)和缓存(caching),以最小化存储开销和解码次数;
  • 积极的资源重用,例如字节数组和Bitmap,以最小化昂贵的垃圾回收和堆碎片影响;
  • 深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。

3. 源码分析

关于Glide的详细使用介绍,参见前面链接即可,但是分析源码也要有个开始吧,那我们就从最基本的用法入手,Glide最基本的用法就是三段论:with、load和into。那我们现在就先从with开始。

3.1 生命周期的作用域(1.Application, 2.Activity, 3.Fragment)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//com.bumptech.glide.Glide.java
public static RequestManager with(@NonNull Context context) {
// getRetriever(context)返回RequestManagerRetriever,下面的生命周期关联会用到
return getRetriever(context).get(context);
}

public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}

public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}

public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getContext()).get(fragment);
}

public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}

从Glide.with()静态方法中,我们可以看到方法可以传入5个参数:Context、Activity、FragmentActivity、Fragment或者View。按照作用域分,我们可以把它分成两类:Application类和非Application类。

  • Application类:它的生命周期是全局的,没有空白Fragment就绑定Activity/Fragment。
  • 非Application类,它的生命周期跟随Activity和Fragment的生命周期,专门有一个空白Fragment绑定Activity/Fragment。

从上面with的重载方法看出都会调用到getRetriever()方法,他其实最终就是返回RequestManagerRetriever对象,紧接着,我们看看RequestManagerRetriever的get方法。这里先分两个来看:

  • Activity、FragmentActivity、Fragment和View
  • Context
3.1.1 Activity类的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
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
//如果不是UI线程,生命周期划分到Application
return get(activity.getApplicationContext());
} else if (activity instanceof FragmentActivity) {
return get((FragmentActivity) activity);
} else {
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
// 不管是Activity、FragmentActivity、Fragment和View的get(),最终都会调用到fragmentGet()
return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
//最终with返回绑定了代理Fragemnt的RequestManager
private RequestManager fragmentGet(
@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//创建一个没有UI的空Fragment来监控用户自定义的Activity生命周期
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
//创建Glide实例
Glide glide = Glide.get(context);
//绑定Glide和空白的Fragemnt
//注意!!:这里创建RequestManager的时候会传入Lifecycle,后面会根据这个lifecycle来透传fragment的生命周期给Glide
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);

if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}
3.1.2 Context类的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
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)) {
// 如果在UI线程,并且是3.1.1小节的组件,就调用Activity类的get(),返回绑定了空Fragment的requestManager
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
// 作用域是Application返回的返回绑定了空Fragment的requestManager
return getApplicationManager(context);
}

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) {
//生命周期和Application一致
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
3.1.3 小结

Glide的with()生命周期总结如下图

作用域总结.png

  • 子线程中Glide调用get()、传入ApplicationContext和ServiceContext,对应的生命周期属于Application域,生命周期和Application一致
  • Activity、Fragment和View对应的生命周期是被代理Fragemnt监控的,Glide内部逻辑会根据Activity的生命周期做相应调整

3.2 Glide生命周期感知过程

如3.1.1小节中分析的,不管with传入的是fragment、Activity还是View,RequestManagerRetriever都会创建一个没有UI的Fragment(SupportRequestManagerFragment)来当代理,当用户自定义的Activity或者Fragment生命周期发生变化的时候,Glide内部可以通过代理Fragment知道生命周期发生的变化,因此内部也做相应的处理。例如下载并且加载是一个比较耗时操作,如果下载完成之后,Activity已经被销毁了,那就不用加载了,所有这就是Glide感知组件生命周期的意义,用户不用主动调用clear()方法来释放资源了。关联关系如下图。

生命周期与组件关联.png

3.3 Glide与空Fragment绑定过程

从3.1.3小结中可以知道,只有在主线程中调用with()并且传入Activity或者Fragment会绑定空Fragment。当传入的activity,这个activity上覆盖的空Fragment是RequestManagerFragment;当传入的是fragment,覆盖在上面的空fragment是SupportRequestManagerFragment。逻辑都是一样的,下面以传入fragment来分析。

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
/** Pending adds for SupportRequestManagerFragments. 
* 空Fragment(SupportRequestManagerFragment)与FragmentManager的映射关系
*/
final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments = new HashMap<>();

private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
// 从三个地方去拿空Fragment,紧接着会分析
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
// 从空Fragment中拿到requestManager
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// 实例化glide用于在创建requestManager的时候绑定glide
Glide glide = Glide.get(context);
// 创建requestManager并且绑定glide
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//如果父fragment可见,就通知glide的onStart()
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}

private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
// 第一个地方:先从FragmentManager中去拿
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
// 第二个地方:从内存中去拿
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//以上两个地方都没有,就创建一个空Fragment然后返回
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
//记录映射关系在内存中,临时存的
pendingSupportRequestManagerFragments.put(fm, current);
//提交Fragment事务
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//如果提交成功之后就删除临时存的映射关系
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}

从supportFragmentGet()方法中我们看到了Glide内部逻辑和空Fragment的绑定过程。

不知道大家有没有疑惑:为什么在getSupportRequestManagerFragment()方法中要在pendingSupportRequestManagerFragments中临时保存空Fragment?

其实就是为了避免 SupportRequestManagerFragment 在一个作用域中重复创建。
因为commitAllowingStateLoss() 是将事务 post 到消息队列中的,也就是说,事务是异步处理的,而不是同步处理的。假设没有临时保存记录,一旦在事务异步等待执行时调用了Glide.with(…) ,就会在该作用域中重复创建 Fragment。

3.4 生命周期的详细监听过程

从上面小节分析可以看出,生命周期的管理,主要对Activity、Fragment和View(实质也是Activity或Fragment)有效,其他的都是Application域,没必须分析。所以后面的分析都是基于Activity或者Fragment的生命周期,而这两个逻辑都是一样的,我们还是以Fragment的分析为例。

从前面看出,每个Activity或者Fragment域都会创建一个空Fragment盖在上面。下来我们就从这个空Fragment开始分析Glide的生命周期是如何受影响的。Fragment盖的空Fragment是SupportRequestManagerFragment.java,那我们就从这里开始。

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
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;

public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}

@VisibleForTesting
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}

@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}

@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}

ActivityFragmentLifecycle getGlideLifecycle() {
return lifecycle;
}
......
}

从3.1.1小节可以看到,创建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
//RequestManagerRetriever.java中
//创建Glide实例
Glide glide = Glide.get(context);
requestManager =factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);

//factory接口
public interface RequestManagerFactory {
@NonNull
RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context);
}

//默认的RequestManager工厂
private static final RequestManagerFactory DEFAULT_FACTORY =
new RequestManagerFactory() {
@NonNull
@Override
public RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};

RequestManager工厂在创建RequestManager的时候,传入了glide和lifecycle,在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
38
39
40
public class RequestManager
implements ComponentCallbacks2, LifecycleListener,...{

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;

......

if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
//lifecycle的生命周期回调加入到RequestManager中
lifecycle.addListener(this);
}

......
}

public synchronized void onStart() {
resumeRequests();
// targetTracker维持着Traker列表,每个Traker属于Glide内部需要监听生命周期的逻辑
targetTracker.onStart();
}

public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
}

至此,生命周期的详细监听过程就通了。

总结:调用with()创建RequestManager,创建RequestManager传入Lifecycle对象(这个对象是在无界面 Fragment 中创建的),RequestManager通过Lifecycle通知Glide内部的各个业务Traker。

当 Fragment 的生命周期变化时,无界面 Fragment会感知到生命周期变化,然后通过Lifecycle 对象将事件分发到 RequestManager,RequestManager的onStart()将事件分发给targetTracker,targetTracker分发给Glide内部逻辑。

参考文档:

1.Glide简介

2.郭霖关于Glide的源码分析