Glide生命周期的原理
Glide.with有很多重载方法:
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
@NonNull
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
其中getRetriever方法是获取RequestManagerRetrieve
r对象,然后调用Get方法。RequestManagerRetriever的get方法看起来有多个重载,参数为context、fragment、activity、view等但实际上只有两种区别,一种是Application类型
的对象时,另一种是非Application
的对象。
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);
}
参数是Application类型的对象时,通过getApplicationManager返回RequestManager对象,getApplicationManager中
绑定application
的生命周期,当程序结束时,glide生命周期结束。
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) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
ApplicationLifecycle
只在addListener时调用onStart方法。
非Application类型
对象,传入的对象不同,但操作的流程是一样的。通过向Activity添加一个无UI Fragment
,来监听Activity的生命周期,然后进行管控。
为什么要添加一个Fragment呢?原因很简单,当我们下载一张图片时,如果当前Activity已经销毁了,那么我们继续下载显然是不合理。因此Glide需要监听Activity的生命周期,但是又没有办法直接获取Activity的生命周期,所以Glide采用添加Fragment的小技巧。我们知道Fragment的生命周期和Activity生命周期是同步的,因此可以通过监听Fragment的生命周期来监听Activity
。这时Glide就可以获取生命周期的事件并且处理加载的流程了。
Fragment和v4.Fragment的不同导致方法最终分别调用了fragmentGet
和supportFragmentGet
,这两个方法操作都是一样的,我们直接看一看fragmentGet:
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = getRequestManagerFragment(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;
}
getRequestManagerFragment是获取Fragment的过程,获取到之后判断绑定的RequestManager是否为空,为空则重新创建绑定。注意RequestManager实现了LifecycleListener,是生命周期环境重要的一项。我们后面来看 现在先来看下真正添加Fragment的过程:
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
getRequestManagerFragment方法会去判断FRAGMENT_TAG标志位的Fragment存不存在,如果存在就返回当前RequestManagerFragment,不存在则从pendingRequestManagerFragments去获取。如果获取不为空,说明当前Fragment真正被添加的过程中,返回当前Fragment不用再次添加,如果为空说明第一次添加,则new一个Fragment添加到Activity。其中pendingRequestManagerFragments添加又通过Handler去删除是为了防止重复添加。
RequestManagerFragment包含了ActivityFragmentLifecycle对象,在构造方法中初始化:
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
}
RequestManagerFragment生命周期方法中回调lifecycle的方法:
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
ActivityFragmentLifecycle生命周期回调的实现:
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
可以看到ActivityFragmentLifecycle的回调代码会遍历lifecycleListeners
,然后调用其对应的回调方法,而lifecycleListeners是通过addListener添加的。
RequestManager实现了LifecycleListener接口,在RequestManagerFactory.Build
时会拿到当前Fragment的生命周期管理属性 current.getGlideLifecycle():
factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
build方法实际上就是获取RequestManager实例的方法:
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
// If we're the application level request manager, we may be created on a background thread.
// In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
// issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
// This should be entirely safe.
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
}
创建时将自身关联到lifecycleListeners中,当Fragment生命周期方法调用时,RequestManager对应的方法也会调用:
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
public void pauseRequests() {
isPaused = true;
for (Request request : Util.getSnapshot(requests)) {
if (request.isRunning()) {
request.clear();
pendingRequests.add(request);
}
}
}
pauseRequests
、resumeRequests
是控制请求加载还是暂停的方法,内部调用的是RequestTracker
对应的pauseRequests方法,进而控制每一个Request请求。