Glide生命周期探索
Glide官网中文版首页简介说到:
深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。
上面写到Glide基于生命周期做了两件事情:
-
优先处理活跃的请求
-
必要时释放资源
Glide又是如何无侵入的获取生命周期的?
网上分析Glide的文章很多,都分析的很清晰,本文是自己分析过程的笔记
切入点
我们以最简单的用法作为切入点进行分析:
Glide.with(imageView).load(url).into(imageView)
追踪过程
绑定生命周期
先看with源码,发现返回了RequestManager,根据注释内容可以确定优先处理活跃的请求就是在此处完成的。它还实现了ComponentCallbacks2、LifecycleListener,直接跳过去看:
public void onTrimMemory(int level) {
if (level == TRIM_MEMORY_MODERATE && pauseAllRequestsOnTrimMemoryModerate) {
// 暂停了所有请求
pauseAllRequestsRecursive();
}
}
public synchronized void onStart() {
// 恢复请求
resumeRequests();
targetTracker.onStart();
}
public synchronized void onStop() {
// 暂停请求
pauseRequests();
targetTracker.onStop();
}
主要由两个类来完成,一个是RequestTracker(不关心),另一个是TargetTracker,注释写到用于持有当前活跃的Target,并且转发生命周期事件。
Target又是什么?TargetTracker#track是唯一添加的调用,直接追踪调用:
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
根据类型不同,返回结果是一个ImageViewTarget,注释写到用于显示resources到ImageView上,它的父类ViewTarget,注释写到用于加载Bitmap到View的默认实现类。
关注点回到生命周期上,跟踪下TargetTracker#onXX的调用,矛头直指ActivityFragmentLifecycle,它也是简单的收集和转发生命周期。追踪下addListener,发现RequestManager确实有添加的过程,具体怎么添加,我们先不管。
发现ActivityFragmentLifecycle的生命周期,由两个Fragment分发(RequestManagerFragment、SupportRequestManagerFragment),ActivityFragmentLifecycle由构造函数注入,但是没有调用,很奇怪,追踪下对外暴露getGlideLifecycle的调用:
private RequestManager fragmentGet(
@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
...
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
...
return requestManager;
}
仅有一处,是在构造RequestManager时所用,原来是共用的同一个,也说明了每个ActivityFragmentLifecycle都对应一个RequestManager。
并且通过传递的FragmentManager和一个Fragment创建了RequestManagerFragment:
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
...
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingRequestManagerFragments.put(fm, current);
// 添加到了fm中
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
...
return current;
}
RequestManagerFragment被添加到了fm中,也就是说,Glide通过在fm中注入一个自己的Fragment来实现绑定生命周期的效果。
无侵入
那么又是如何实现无侵入的?追踪下这个FragmentManager是怎么来的,最终都是回归到with方法,看看到底是怎么拿的:
public RequestManager get(@NonNull Activity activity) {
...
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
public RequestManager get(@NonNull android.app.Fragment fragment) {
...
android.app.FragmentManager fm = fragment.getChildFragmentManager();
return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
}
public RequestManager get(@NonNull View view) {
...
Activity activity = findActivity(view.getContext());
...
if (activity == null) {
// 处理非activity的情况
return get(view.getContext().getApplicationContext());
}
// 处理用户在FragmentActivity嵌套Support包内Fragment的情况
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
return fragment != null ? get(fragment) : get((FragmentActivity) activity);
}
// 处理Activity嵌套旧Fragment的情况
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
public RequestManager get(@NonNull Context context) {
...
// 不属于Fragment、Activity、FragmentActivity的情况
return getApplicationManager(context);
}
Activity和Fragment比较简单,继续看看View和Context的情况:
private RequestManager getApplicationManager(@NonNull Context context) {
// Either an application context or we're on a background thread.
...
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
return applicationManager;
}
在Context的情况下,且不属于Fragment、Activity、FragmentActivity的情况,Glide将ApplicationLifecycle整个应用的生命周期传给了RequestManager,也就是相当于是没有生命周期
private Fragment findSupportFragment(@NonNull View target, @NonNull FragmentActivity activity) {
tempViewToSupportFragment.clear();
// 收集所有fragment的根View,和fragment组成map
findAllSupportFragmentsWithViews(
activity.getSupportFragmentManager().getFragments(), tempViewToSupportFragment);
Fragment result = null;
// 当前FragmentActivity的根view的容器
View activityRoot = activity.findViewById(android.R.id.content);
View current = target;
while (!current.equals(activityRoot)) {
result = tempViewToSupportFragment.get(current);
if (result != null) {
break;
}
if (current.getParent() instanceof View) {
// 不断往上
current = (View) current.getParent();
} else {
break;
}
}
tempViewToSupportFragment.clear();
return result;
}
在嵌套的情况下,通过遍历当前Activity下的所有Fragment的根View,找到和当前View的根View匹配的Fragment,剩下流程和传入Fragment的流程相同