美文网首页
Glide源码解读(一)-- 图片加载的生命周期

Glide源码解读(一)-- 图片加载的生命周期

作者: IN_BLACK_IN | 来源:发表于2018-02-26 17:37 被阅读0次

    先来看下glide的一般使用方法

    Glide.with(context).load(url).into(mImageView);
    

    其中Glide.with(context)这一步就完成了图片加载时的生命周期绑定,可见glide调用简单,然而其在背后的逻辑却很复杂,接下来我们从源码的角度去解读glide如何用一句话完成了这么多事。

    我们以context对象是Activity为例,进入到Glide.with(context) 这个方法中

    RequestManagerRetriever
    public RequestManager get(@NonNull Activity activity) {
      if (Util.isOnBackgroundThread()) {
        // 如果不是主线程,则context对象转为ApplicationContext,然后也不做绑定生命周期的操作,
        // 图片加载的生命周期默认为Application的生命周期
        return get(activity.getApplicationContext());
      } else {
        assertNotDestroyed(activity);
        android.app.FragmentManager fm = activity.getFragmentManager();
        return fragmentGet(activity, fm, null /*parentHint*/);
      }
    }
    

    接着进入fragmentGet方法

    private RequestManager fragmentGet(@NonNull Context context,
        @NonNull android.app.FragmentManager fm,
        @Nullable android.app.Fragment parentHint) {
      // 获取到一个无UI的Fragment,用来绑定Activity从而实现生命周期同步
      // 因为glide无法直接获取activity的生命周期,通过activity的FragmentManager中加入一个隐藏的fragment,
      // 因为fragment与传入的activity生命周期一致,所以只要监听这个RequestManagerFragment就能实现生命周期管理
      RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
      RequestManager requestManager = current.getRequestManager();
      ......
      return requestManager;
    }
    

    我们具体看下fragment的创建过程

    RequestManagerFragment getRequestManagerFragment(
        @NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
      // 由于这个Fragment是个无UI的Fragment,可以通过findFragmentByTag(FRAGMENT_TAG)去查找这个RequestManagerFragment
      // 但如果第一次进来,current就是null,如果已经创建过,可以通过fm对象找到已有的fragment对象
      // 无UI查找Fragment参考文章 http://blog.csdn.net/llp1992/article/details/41828237
      RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
      if (current == null) {
        current = pendingRequestManagerFragments.get(fm);
        if (current == null) {
          // 初始化RequestManagerFragment并且绑定FRAGMENT_TAG放入FragmentManager
          current = new RequestManagerFragment();
          ......
        }
      }
      return current;
    }
    

    接着我们进入RequestManagerFragment的构造方法中查看初始化的时候做了些什么

    public class SupportRequestManagerFragment extends Fragment {
      
      public SupportRequestManagerFragment() {
        // 初始化Fragment的时候也顺便初始化了ActivityFragmentLifecycle
        this(new ActivityFragmentLifecycle());
      }
    
      @SuppressLint("ValidFragment")
      public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
        // lifecycle赋值
        this.lifecycle = lifecycle;
      }
    
      /**
       * 在构造方法中{@link #SupportRequestManagerFragment(ActivityFragmentLifecycle)}
       * 初始化lifecycle
       */
      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();
      }
    }
    

    我们可以看下上面这个类的部分代码,在初始化Fragment的时候也顺带初始化了ActivityFragmentLifecycle,并赋值给lifecycle,在fragment的生命周期方法中,比如onStart方法中,调用了lifecycle.onStart(),由于fragment和绑定的activity生命周期基本一样,这样的话lifecycle对象也就带有刚开始传入Glide.with(context)这个context对象的生命周期,可以通过fragment对象的getGlideLifecycle()方法获取到这个带有生命周期的自定义类的对象。

    到这里,基本就知道了glide怎么去获取到当前上下文对象的生命周期变化,接下去我们继续分析,glide获取到生命周期后去做了些什么事情。

    首先来看下这个自定义的生命周期自定义类

    class ActivityFragmentLifecycle implements Lifecycle {
      
      @Override
      public void addListener(LifecycleListener listener) {
        lifecycleListeners.add(listener);
    
        if (isDestroyed) {
          listener.onDestroy();
        } else if (isStarted) {
          listener.onStart();
        } else {
          listener.onStop();
        }
      }
    
      @Override
      public void removeListener(LifecycleListener listener) {
        lifecycleListeners.remove(listener);
      }
    
      void onStart() {
        isStarted = true;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
          lifecycleListener.onStart();
        }
      }
    
      void onStop() {
        isStarted = false;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
          lifecycleListener.onStop();
        }
      }
    
      void onDestroy() {
        isDestroyed = true;
        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
          lifecycleListener.onDestroy();
        }
      }
    }
    
    public interface Lifecycle {
      void addListener(LifecycleListener listener);
      void removeListener(LifecycleListener listener);
    }
    

    ActivityFragmentLifecycle 实现了Lifecycle,对外暴露一个addListener方法,可以监听生命周期的变化。到这里,监听生命周期的准备工作都已经完成,就等其他想要使用的地方去实现这个监听器了,所以我们回过头去看下哪里实现了这个监听器。


    接下来我们回到上文中的fragmentGet方法,刚刚看了部分代码,现在我把这个方法的全部代码贴出来

    private RequestManager fragmentGet(@NonNull Context context,
        @NonNull android.app.FragmentManager fm,
        @Nullable android.app.Fragment parentHint) {
      // 获取到一个无UI的Fragment,用来绑定Activity从而实现生命周期同步
      // 因为glide无法直接获取activity的生命周期,通过activity的FragmentManager中加入一个隐藏的fragment,
      // 因为fragment与传入的activity生命周期一致,所以只要监听这个RequestManagerFragment就能实现生命周期管理
      RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
      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;
    }
    

    上面我们用大篇幅解析了这一行代码 RequestManagerFragment current = getRequestManagerFragment(fm, parentHint),接下去我们接着走下去。接着执行 RequestManager requestManager = current.getRequestManager(),当第一次执行 current.get 方法的时候,返回的 requestManager 对象是null,所以我们重点分析下if里面的代码块。

    我们进入factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context)方法中

    public interface RequestManagerFactory {
      @NonNull
      RequestManager build(
          @NonNull Glide glide,
          @NonNull Lifecycle lifecycle,
          @NonNull RequestManagerTreeNode requestManagerTreeNode,
          @NonNull Context context);
    }
    
    private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
      @NonNull
      @Override
      public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
          @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
        // 在这里初始化RequestManager
        return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
      }
    };
    

    其中factoryRequestManagerRetriever构造方法中被赋值:this.factory = factory != null ? factory : DEFAULT_FACTORY,故 factory.build 最终执行的是return new RequestManager(glide, lifecycle, requestManagerTreeNode, context)。其中lifecycle正是我们前面创建fragment生成的带有生命周期的自定义类。

    我们进入RequestManager的构造方法,查看下RequestManager整个类的关键代码

    public class RequestManager implements LifecycleListener {
    
      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 {
          // RequestManager 实现了LifecycleListener,然后和lifecycle实现了绑定
          lifecycle.addListener(this);
        }
      }
    
      @Override
      public void onStart() {
        resumeRequests();
        targetTracker.onStart();
      }
    
      @Override
      public void onStop() {
        pauseRequests();
        targetTracker.onStop();
      }
    
      @Override
      public void onDestroy() {
        targetTracker.onDestroy();
        for (Target<?> target : targetTracker.getAll()) {
          clear(target);
        }
        targetTracker.clear();
        requestTracker.clearRequests();
        lifecycle.removeListener(this);
        lifecycle.removeListener(connectivityMonitor);
        mainHandler.removeCallbacks(addSelfToLifecycle);
        glide.unregisterRequestManager(this);
      }
    }
    

    RequestManager从类名来看,应该就是请求管理类,它自身实现了LifecycleListener,在自身的构造方法中,和lifecycle进行了绑定,这样我们先前初始化的fragment的生命周期就在这里实现了监听,我们可以看下RequestManager生命周期方法中的一些代码,resumeRequests()pauseRequests(),顾名思义,他在执行相应生命周期的时候做了重新发送请求、暂停请求、销毁请求等操作。

    到这里,我们就对glide的生命周期有了完整的了解,图片在加载时,会根据传入context对象的生命周期变化而做出暂停、销毁请求等操作,其中实现的主要原理就是glide生成了一个没有UI的Fragment同步context对象的生命周期,然后对这个自定义的Fragment进行监听,从而处理其他加载逻辑。

    相关文章

      网友评论

          本文标题:Glide源码解读(一)-- 图片加载的生命周期

          本文链接:https://www.haomeiwen.com/subject/cdgyxftx.html