在前面Glide鉴赏文章中,我们从整体架构和加载图片的完整流程对Glide进行了详细的分析,希望大家能对Glide有大概的理解,常言道:取其精华,去其糟粕,与其深陷在源码中,不如看看真正值得我们学习的是什么
Glide有个特性是可以依赖页面生命周期动态控制加载图片,比如在页面不可见时暂停加载,页面恢复时继续加载图片。其实现思想如下:
1 获取FragmentManager
在Glide.with流程中,调用RequestManagerRetriever#get这一步,根据传入Context类型和当前线程获取当前页面的FragmentManager
- 若是在子线程或传入的Context为Application,最终调用RequestManagerRetriever#getApplicationManager,传入的是Application Context构建RequestManager,生命周期和App一致。
- 若是在主线程,根据Context类型,获取到当前页面的FragmentManager,如下源码所示
@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.getContext(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getContext().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
}
}
2 构建SupportRequestManagerFragment
在上面获取到的FragmentManager中,先查找是否已经存在当前页面对应的SupportRequestManagerFragment,若不存在,则进行构建,并将其添加到上面获取到的FragmentManager中。对于SupportRequestManagerFragment,我们需要关注其内部这个对象ActivityFragmentLifecycle
ActivityFragmentLifecycle是用于添加依赖生命周期监听的对象。在SupportRequestManagerFragment构造时创建,只要实现了LifecycleListener接口的对象,都可以添加到弱引用的Set中,防止重复添加和内存泄漏。在SupportRequestManagerFragment的onStart,onStop,onDestroy会回调ActivityFragmentLifecycle对象的对应方法,从而对ActivityFragmentLifecycle内部添加的监听对象也进行遍历,调用各自的生命周期方法
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
private RequestManager requestManager;
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
ActivityFragmentLifecycle getGlideLifecycle() {
return lifecycle;
}
public void setRequestManager(@Nullable RequestManager requestManager) {
this.requestManager = requestManager;
}
public RequestManager getRequestManager() {
return requestManager;
}
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
// ...onStop, onDestory
}
class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
//...onStop,onDestroy
}
3 构建RequestManager和绑定监听
在构建了SupportRequestManagerFragment后,也是先从中获取RequestManager,即当前页面的请求管理器。若没有,则传入上面SupportRequestManagerFragment内部的ActivityFragmentLifecycle对象current.getGlideLifecycle(),构建出RequestManager,在RequestManager构造方法中,会将自身添加进传入的ActivityFragmentLifecycle对象里。如此,就将RequestManager和SupportRequestManagerFragment的生命周期方法绑定了
// RequestManagerRetriever.java
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) {
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
以页面不可见时暂停加载为例,SupportRequestManagerFragment会执行onStop,流程如下图
public class RequestManager implements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> {
public RequestManager(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode,
@NonNull Context context) {
//...
}
@Override
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
}