Glide 源码解析之监听生命周期

栏目: IT技术 · 发布时间: 4年前

内容简介:作者:断了谁的弦链接:https://www.jianshu.com/p/1169a91342a9

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实现了该接口,所以就可以在相应的生命周期执行请求的开始和暂停等操作。


以上所述就是小编给大家介绍的《Glide 源码解析之监听生命周期》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Eric Meyer on CSS

Eric Meyer on CSS

Eric Meyer / New Riders Press / 2002-7-8 / USD 55.00

There are several other books on the market that serve as in-depth technical guides or reference books for CSS. None, however, take a more hands-on approach and use practical examples to teach readers......一起来看看 《Eric Meyer on CSS》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码