本文将从源码的角度,分析Glide是如何关联生命周期的。
如无特殊说明,源码版本均指:4.6.1
学习Glide是如何关联生命周期的,核心在于一个知识点:
fragment
的生命周期,是与Activity
生命周期对应的。
明白并牢记这一点可,以更好的理解本文。
一.生命周期绑定
我们先以继承AppCompatActivity
(它的父类是FragmentActivity
)为例分析。在第3部分,我们再进行拓展到一般情况。
Glide
加载图片最基本的方式如下:
Glide.with(MainActivity.this).load(url).into(mImageView);
Glide
生命周期绑定是从入口单例类Glide
开始的,通过with()
多个重载方法来实现对生命周期的绑定工作。
1. with()方法
这个方法有多个重载,可以传入Context
、Activity
、Fragment
、View
等,但是内部调用方法都是一样的,只是参数有所不同,这里以传入FragmentActivity
为例。
代码片1
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
第4行代码中, getRetriever(activity)
,返回的是 RequestManagerRetriever
第4行代码 整体看,即看 RequestManagerRetriever.class
中的get
方法:
代码片2 #RequestManagerRetriever.class
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
//如果是在子线程
if (Util.isOnBackgroundThread()) {
--->第2部分会分析(2A)
return get(activity.getApplicationContext());
} else {
//如果是在主线程
assertNotDestroyed(activity);
//获取当前Activity的FragmentManager
//用于后续将创建的Fragment绑定到activity
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, null /*parentHint*/);
}
}
那我们看一下supportFragmentGet
方法:
代码片3 #RequestManagerRetriever.class
@NonNull
private RequestManager supportFragmentGet(@NonNull Context context, @NonNull FragmentManager fm,
@Nullable Fragment parentHint) {
//创建无UI的fragment(第2部分分析),并绑定到当前activity
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint); --->分析3A
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
//创建RequestManager,获取fragment的lifecycle,传入requestManager
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
我们看一下3A(代码片3第8行)的SupportRequestManagerFragment
是如何获取的。进入getSupportRequestManagerFragment
方法:
代码片4 #RequestManagerRetriever.class
// pendingSupportRequestManagerFragments是一个map集合
@VisibleForTesting
final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments =
new HashMap<>();
@NonNull
SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
//1、由FragmentManager通过tag获取fragment
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//2、从缓存集合中获取fragment的,map以fragmentManger为key,
//以fragment为value进行存储
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//3、创建一个fragment实例
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget(); ---(第3部分会分析)分析4A
}
}
return current;
}
小结:
1、创建无UI
的Fragment
,并绑定到当前activity
;
2、通过builder
模式创建RequestManager
,并且将fragment
的lifecycle
传入,这样Fragment
和RequestManager
就建立了联系;
3、获取Fragment
对象,先根据tag
去找,如果没有从内存中查找,pendingSupportRequestManagerFragments
是一个存储fragment
实例的HashMap
,再没有的话就new
一个。
2. SupportRequestManagerFragment 类
我们看一下SupportRequestManagerFragment
类具体是怎么样的?
代码片5 SupportRequestManagerFragment.class
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;
}
@NonNull
ActivityFragmentLifecycle getGlideLifecycle() {
return lifecycle;
}
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop(