code小生 一个专注大前端领域的技术平台公众号回复Android
加入安卓技术群
作者:断了谁的弦
链接:https://www.jianshu.com/p/1169a91342a9
声明:本文已获断了谁的弦
授权发表,转发等请联系原作者授权
虽然之前就知道Glide是通过创建一个Fragment来监听生命周期的,但是直到面试被问到时才发现自己只是知道有这件事,里面的具体实现简直就是一无所知,所以本文就来探究一下Glide是如何监听生命周期的。
在上文Glide源码解析之with()中我们说到里面会创建一个SupportRequestManagerFragment并通过FragmentManager添加到当前的Activity/Fragment中,然后把它的GlideLifecycle赋值给requestManager。
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) {
// 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;
}
SupportRequestManagerFragment是一个继承了android.support.v4.app.Fragment的Fragment。此外还有一个RequestManagerFragment,它继承的是android.app.Fragment。两者的内部实现基本一致,它们里面都有一个ActivityFragmentLifecycle,这是一个里面持有了LifecycleListener集合的类,而LifecycleListener就是我们监听生命周期的关键,里面定义了几个生命周期方法,在SupportRequestManagerFragment执行到相关的生命周期时就会回调LifecycleListener相应的方法。
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@NonNull
ActivityFragmentLifecycle getGlideLifecycle() {
return 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();
}
}
class ActivityFragmentLifecycle implements Lifecycle {
private final Set lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap());
}
public interface LifecycleListener {
/**
* Callback for when {@link android.app.Fragment#onStart()}} or {@link
* android.app.Activity#onStart()} is called.
*/
void onStart();
/**
* Callback for when {@link android.app.Fragment#onStop()}} or {@link
* android.app.Activity#onStop()}} is called.
*/
void onStop();
/**
* Callback for when {@link android.app.Fragment#onDestroy()}} or {@link
* android.app.Activity#onDestroy()} is called.
*/
void onDestroy();
}
在上面我们知道了把SupportRequestManagerFragment里面的ActivityFragmentLifecycle赋值给了RequestManagerFactory的build方法去生成RequestManager,而RequestManager实现了LifecycleListener接口,并在构造函数里面调用了lifecycle.addListener(this),所以当Fragment的生命周期发生变化时RequestManager就会监听到。
private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
public class RequestManager implements LifecycleListener,
ModelTypes> {
private final RequestTracker requestTracker;
private final TargetTracker targetTracker = new TargetTracker();
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()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
}
在看生命周期之前先来看两个关键的类,RequestTracker主要用来统一管理Request,对它们进行开始和暂停等操作。
TargetTracker则用来统一管理Target(在使用Glide最后调用into(imageView)的时候会包装成一个Target,例如DrawableImageViewTarget)的生命周期回调。
public class RequestTracker {
private final Set requests =
Collections.newSetFromMap(new WeakHashMap());
//暂停的请求会保存在这里
private final List pendingRequests = new ArrayList<>();
}
public final class TargetTracker implements LifecycleListener {
private final Set> targets =
Collections.newSetFromMap(new WeakHashMap, Boolean>());
}
在onStart()里面会调用RequestTracker的resumeRequests()来开始请求
//RequestManager
@Override
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
public synchronized void resumeRequests() {
requestTracker.resumeRequests();
}
//RequestTracker
public void resumeRequests() {
isPaused = false;
for (Request request : Util.getSnapshot(requests)) {
if (!request.isComplete() && !request.isRunning()) {
request.begin();
}
}
pendingRequests.clear();
}
同时会调用TargetTracker的onStart(),里面会回调animatable的start()方法,如果有动画的话会从这里开始执行。
//TargetTracker
@Override
public void onStart() {
for (Target> target : Util.getSnapshot(targets)) {
target.onStart();
}
}
//ImageViewTarget(DrawableImageViewTarget继承于它)
@Override
public void onStart() {
if (animatable != null) {
animatable.start();
}
}
在onStop()里面停止正在运行的request,并且加入到pendingRequests里面,然后停止动画的执行。
//ReuqestManager
@Override
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
public synchronized void pauseRequests() {
requestTracker.pauseRequests();
}
//RequestTracker
public void pauseRequests() {
isPaused = true;
for (Request request : Util.getSnapshot(requests)) {
if (request.isRunning()) {
request.clear();
pendingRequests.add(request);
}
}
}
//ImageViewTarget
@Override
public void onStop() {
if (animatable != null) {
animatable.stop();
}
}
在onDestroy()里面取消所有进行中的请求,并且对已经完成的请求进行清除以及回收资源。
@Override
public synchronized void onDestroy() {
targetTracker.onDestroy();
for (Target> target : targetTracker.getAll()) {
clear(target); //删除target里面的request,并且取消request以及释放资源
}
targetTracker.clear(); //清空target集合
requestTracker.clearRequests(); //取消全部请求并且清空它们资源
lifecycle.removeListener(this); //不再监听生命周期
}
Glide通过在当前Activity/Fragment里添加一个Fragment,在Fragment的生命周期里回调LifecycleListener的相应方法,而RequestManager实现了该接口,所以就可以在相应的生命周期执行请求的开始和暂停等操作。
1 Android 【手撕Glide】--Glide是如何关联生命周期的?
2 Android项目重构实践:从 Fresco 到 Glide 低成本重构方案
3 Glide 架构设计艺术
4 Android 基于 glide 4.0 封装图片加载库
5 Android 框架思考--工具类设计(Glide、Picasso切换实现)
如果你有写博客的好习惯
欢迎投稿
点个在看,小生感恩❤️