Glide 源码解析之监听生命周期
source link: http://mp.weixin.qq.com/s?__biz=MzIxNzU1Nzk3OQ%3D%3D&%3Bmid=2247490118&%3Bidx=1&%3Bsn=eb7dbeda2cfd92527aeda016c4233aa7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
code小生
一个专注大前端领域的技术平台
公众号回复 Android
加入安卓技术群
作者:断了谁的弦
链接:https://www.jianshu.com/p/1169a91342a9
声明:本文已获 断了谁的弦
授权发表,转发等请联系原作者授权
前言
虽然之前就知道Glide是通过创建一个Fragment来监听生命周期的,但是直到面试被问到时才发现自己只是知道有这件事,里面的具体实现简直就是一无所知,所以本文就来探究一下Glide是如何监听生命周期的。
SupportRequestManagerFragment的创建
在上文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是什么
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<LifecycleListener> lifecycleListeners = Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>()); } 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<RequestBuilder<Drawable>> { 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<Request> requests = Collections.newSetFromMap(new WeakHashMap<Request, Boolean>()); //暂停的请求会保存在这里 private final List<Request> pendingRequests = new ArrayList<>(); } public final class TargetTracker implements LifecycleListener { private final Set<Target<?>> targets = Collections.newSetFromMap(new WeakHashMap<Target<?>, 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实现了该接口,所以就可以在相应的生命周期执行请求的开始和暂停等操作。
Recommend
-
30
Github: Glide 分析版本: 85bf0c3 An image loading and caching libra...
-
9
手写Vue源码(四) - 生命周期夏日Enjoy what you are doing! 源码地...
-
16
Spring Bean的生命周期真的是面试的时候关于Spring的最高频的考点之一了,笔者曾经被这个问题问懵了不止一次,一直记不住那一大串的步骤,但实际上尝试去死记硬背那些步骤的我是错误的,表面上看只是背诵一个流程,实际上,这个流程牵扯到的知识点...
-
11
时序数据库Influx-IOx源码学习七(Chunk的生命周期) - 刘涛华的个人空间 - OSCHINA - 中文开源技术交流社区 仅限深圳|现场揭秘:腾讯云原生...
-
6
react源码解析11.生命周期调用顺序视频讲解(高效学习):
-
7
IOC加载过程 Bean的生命周期 比如,现在有A, B两个类, 在A类中引用了B类. 那么如果有一天, B类要被替换掉, 我们会怎么办呢?如...
-
4
转载请注明出处: 1.SpringBoot 源码执行流程图 2. 创建SpringApplication 应用,在构造函数中推断启动应用类型,并进行spring boot自动装配 public static ConfigurableApplicationContext run(Class<?>[] primarySour...
-
8
Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点 none参考了Spring 官网文档 https://docs.spring.io/spring-f...
-
3
Spring源码:bean的生命周期(一) 本节将正式介绍Spring源码细节,将讲解Bean生命周期。请注意,虽然我们...
-
5
Spring源码:Bean的生命周期(二) 让我们继续讲解Spring的Bean实例化过程。在上一节中,我们已经讲解了Sp...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK