Glide 4.12 框架源码中的生命周期设计

Posted hymKing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Glide 4.12 框架源码中的生命周期设计相关的知识,希望对你有一定的参考价值。

在上一篇文章《最新源码Glide4.12框架之加载图片流程源码分析》中,我们主要做了对于通过Glide.with(this).load(url).into(target)的调用图片加载流程的的源码分析,以及对加载流程图的梳理。

本篇文章主要对Glide图片框架的生命周期感知进行源码分析,体会Glide是如何做到感知Activity、Fragment的生命周期并控制自身图片加载过程的生命周期的。

一、初识Glide图片加载生命周期

  • 深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。

上述文字是Glide官方文档中对Glide的生命周期的介绍,Glide图片加载框架的加载行为,会随着Activity、Fragment生命周期的变化而变化,当一个Activity或者Fragment销毁的时候,生命周期的回调函数被调用,触发Glide图片加载的停止,可以避免内存泄漏,是对手机系统资源利用效率的提升。

二、生命周期实现详解

还是从上面一篇文章中最基本的使用Demo入手:

public class MainActivity extends AppCompatActivity 
    String url = "";
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        imageView = findViewById(R.id.img_glide);
        //通过链式调用的方式加载一张图片
        Glide.with(this).load(url).into(imageView);
    

Glide.with方法的重载函数有如下几种情况:

public class Glide implements ComponentCallbacks2 
   /**使用上下文启动的任何请求将应用Application级别的options,不会根据生命周期时间启动和停止
     *这个方法适用于在普通的Fragment、Activity之外的使用场景,比如在Service中、notification
     *中的缩略图
     */
  public static RequestManager with(@NonNull Context context) 
    return getRetriever(context).get(context);
  
  /**启动一个加载绑定在Activity的生命周期上,并使用Activity的默认options
   */
  public static RequestManager with(@NonNull Activity activity) 
    return getRetriever(activity).get(activity);
  
  /**启动一个加载绑定在FragmentActivity的生命周期上,并使用FragmentActivity的默认options
   */
  public static RequestManager with(@NonNull FragmentActivity activity) 
    return getRetriever(activity).get(activity);
  
  /**启动一个加载绑定在Fragment的生命周期上,并使用Fragment的默认options
   */
  public static RequestManager with(@NonNull Fragment fragment) 
    return getRetriever(fragment.getContext()).get(fragment);
  

上面四个with重载方法的文档注释部分都做中文翻译,显然with(context)的情况,我们就不用分析了。另外的三个重载函数表达都是和Activity、Fragment生命周期的绑定,Fragment的生命周期本质上是有Activity的生命周期函数驱动的。所以接下来,我们只要分析with(Activity)的实现源码分析,其它两种情况是类比相似的。RequestManagerRetriever.get()方法的调用:

public class RequestManagerRetriever implements Handler.Callback 
  @SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull Activity activity) 
    //非主线程
    if (Util.isOnBackgroundThread()) 
      //返回和applicationContext关联的RequestManager
      return get(activity.getApplicationContext());
     else if (activity instanceof FragmentActivity) 
      //FragmentActivity 调用此方法
      return get((FragmentActivity) activity);
     else 
      assertNotDestroyed(activity);
      frameWaiter.registerSelf(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      //Activity最终会调用此方法
      return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    
  
  
  public RequestManager get(@NonNull FragmentActivity activity) 
    if (Util.isOnBackgroundThread()) 
      return get(activity.getApplicationContext());
     else 
      assertNotDestroyed(activity);
      frameWaiter.registerSelf(activity);
      //fragment管理者对象
      FragmentManager fm = activity.getSupportFragmentManager();
      //FragmentAcitivty最终会调用此方法
      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    
  
 

2.1 创建空fragment并注入requestManger

通过上述的代码注释的分析,最终都会调用到supportFragmentGet(),在这个方法中完成了生命周期的绑定过程,并且在符合条件的情况下,调用RequestManager的onStart方法。

@NonNull
private RequestManager supportFragmentGet(
    @NonNull Context context,
    @NonNull FragmentManager fm,
    @Nullable Fragment parentHint,
    boolean isParentVisible) 
  //查看supportRequest的源码,文档注释部分说明如下:
  /**一个无view的fragment用于安全的持有requestManager用于开始、停止和管理glide的请求
   *这个fragment作为子组件被添加到Activity或是Fragment上*/
  SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
  //获取持有的requestManager
  RequestManager requestManager = current.getRequestManager();
  //如果requestManager为空
  if (requestManager == null) 
    Glide glide = Glide.get(context);
    //通过工厂方法创建一个requestManger
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    //这里实际就是isActivityVisable
    if (isParentVisible) 
      //requestManger调用onStart
      requestManager.onStart();
    
    //且把当前的fragment中注入requestManger,和requestManager进行绑定
    current.setRequestManager(requestManager);
  
  return requestManager;

SupportRequestManagerFragment 是一个无view的Fragment,通过getSupportRequestManagerFragment方法获取和创建,我们看一下创建和获取的源代码:

public class RequestManagerRetriever implements Handler.Callback 
  @NonNull
  private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint) 
    //根据tag从fragmentManger中获取
    SupportRequestManagerFragment current =
        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) 
      //没有获取达到从内存的一个map集合中获取
      current = pendingSupportRequestManagerFragments.get(fm);
      if (current == null) 
        //还没有获取到,则直接new一个fragment,在上段源码注释中已经说明,此是一个无view的frag
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        //添加到内存map集合中,待用。相同的Activity中加载图片的时候,就可以获取到了,主要依赖于
        //fragmentManger对象是否相同,查询条件传入的参数就是fm实例
        pendingSupportRequestManagerFragments.put(fm, current);
        //添加、提交
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        //删除临时临时映射关系,不用管这块
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
      
    
    return current;
  

从这段源码中可以看到,同一个activity中加载不同图片的时候,空fragment对象实例是可以重复使用的。通过pendingSupportRequestManagerFragments这个map集合进行维护,也可以避免重复创建。

2.2 生命周期的的绑定、监听过程实现分析

从上段的分析,我们知晓创建的空fragment就是用于生命周期感知的,且在这个空fragment中注入了RequestManger实例对象。我们接下来,完整的看一下,这个特定的fragment内部的实现。查看SupportRequestManagerFragment的源码如下:

/**一个无view的fragment用于安全的持有requestManager用于开始、停止和管理glide的请求
 *这个fragment作为子组件被添加到Activity或是Fragment上*/
public class SupportRequestManagerFragment extends Fragment 
  //Glide包自带的lifecycle组件(和androidx中相关lifecycle组件区分开)
  private final ActivityFragmentLifecycle lifecycle;
  ....
  @Nullable private RequestManager requestManager;
  //new对象进行创建的时候,构建了一个lifecycle对象
  public SupportRequestManagerFragment() 
    this(new ActivityFragmentLifecycle());
  
  //成员变量lifecycle被赋值
  public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) 
    this.lifecycle = lifecycle;
  
  //提供设置注入requestManger方法
  public void setRequestManager(@Nullable RequestManager requestManager) 
    this.requestManager = requestManager;
  
  //提供获取当前fragment的lifecycle
  ActivityFragmentLifecycle getGlideLifecycle() 
    return lifecycle;
  
  //获取requestManager方法
  public RequestManager getRequestManager() 
    return requestManager;
  
  ......非生命周期相关代码省略....
  //以下fragment本身生命周期方法的回调(这个不用多说,系统级别的api已经帮我们实现了这个回调)
  @Override
  public void onStart() 
    super.onStart();
    //回调glide的生命周期组件lifecycle.onStart
    lifecycle.onStart();
  
  @Override
  public void onStop() 
    super.onStop();
    //回调glide的生命周期组件lifecycle.onStop
    lifecycle.onStop();
  
  @Override
  public void onDestroy() 
    super.onDestroy();
    lifecycle.onDestroy();
    //回调glide的生命周期组件lifecycle.onDestroy
    unregisterFragmentWithRoot();
  
  .....

上述源码中的注释真的已经非常详细,我们也看到了和Glide生命周期最直接相关的类Lifecycle,实际上个接口,我们看一下究竟:

package com.bumptech.glide.manager;
import androidx.annotation.NonNull;
/** 一个监听接口,监听Activity和fragment的生命周期事件 */
public interface Lifecycle 
  void addListener(@NonNull LifecycleListener listener);
  void removeListener(@NonNull LifecycleListener listener);

LifecycleListener,我们也看一下:

/**
 * 真正的监听生命周期事件接口,有onStart、onStop、onDestroy
 */
public interface LifecycleListener 
  void onStart();
  void onStop();
  void onDestroy();

分析到这个位置,至少我们已经很清晰Glide的生命周期感知函数,并不想Activity、Fragment那样有那么多,就三个生命周期函数,分别是onStart、onStop、onDestroy。Glide的这三个生命周期正好的对应Activity、Fragment中的onStart、onStop、onDestory的调用来进行回调。具体怎么回调的,看代码层的实现,在上段SupportRequestManagerFragment的onStart方法中进行了lifecycle.onStart()的调用,lifecycle实例的实现例是ActivityFragmentLifecycle,查看源码:

class ActivityFragmentLifecycle implements Lifecycle 
  private final Set<LifecycleListener> lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
  ...
  @Override
  public void addListener(@NonNull LifecycleListener listener) 
    ....
  
  @Override
  public void removeListener(@NonNull LifecycleListener listener) 
    ....
  
  // lifecycle.onStart()方法的调用在这
  void onStart() 
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners))      //回调了Glide中lifecycleListener的onStart
      lifecycleListener.onStart();
    
  
  ....onStop、onDestory...

接下来我们是需要这里的lifecycle是谁,glide生命周期的监听过程我们就搞清楚了。还记得,我们前端代码在创建空Fragment的时候的这段代码吗?

requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);

通过工厂创建requestManger的时候,我们传入了当前这个空fragment穿件的glide的生命周期对象,addLifecycleListener就是在工厂方法最后调用的requestManger中去实现的。查看源码RequestManager的构造函数:

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()) 
    Util.postOnUiThread(addSelfToLifecycle);
   else 
    //主线程调用(和前面的分析也是一致的)
    lifecycle.addListener(this);
  
  lifecycle.addListener(connectivityMonitor);

  defaultRequestListeners =
      new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
  setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

  glide.registerRequestManager(this);

lifecycle是空fragment中创建的lifecycle,addListener(this)中this就是requestManger,很显然requestManger实现了lifecycleListener的接口。

到此,小结一下:

第一步:我们添加的空Fragment中的生命周期方法(如onStart)执行,回调内部创建的ActivityFragmentLifecycle的生命周期方法(如onStart),

第二步:再在ActivityFragmentLifecylce中回调监听器的生命周期方法(如onStart),而监听器本质上就是RequestManger,实际上回调的就是requestManger的生命周期方法。

第三步:requestManger中的生命周期方法被调用,执行生命周期方法内的所需操作。

简单看一下,第三步中如果是onStop方法被调用,会干啥:

public synchronized void onStop() 
  //停止请求
  pauseRequests();
  targetTracker.onStop();

public synchronized void pauseRequests() 
  //交给requestTracker停止请求
  requestTracker.pauseRequests();

public class RequestTracker 
   public void pauseRequests() 
    isPaused = true;
    for (Request request : Util.getSnapshot(requests)) 
      if (request.isRunning()) 
        //请求停止
        request.pause();
        //添加到等待队列
        pendingRequests.add(request);
      
    
  

三、总结

Glide的生命周期方法有三个onStart、onStop、onDestory。

Glide框架设计了lifecycle接口,用于添加生命周期的监听器ifecycleListener。

Glide在调用with方法的时候,去创建一个空Fragment,空Fragment中创建了ActivityFragmentLifecycle生命周期实例。

Glide在调用with方法中,去创建Glide、创建requestManger和Glide绑定,requestManger创建时传入空Fragment的生命周期对象ActivityFragmentLifecycle,并将自身做未监听器添加其中。

通过上述流程,Activity、Fragment的原生生命周期方法调用的时候,进行lifecycle对象调用,最终会调到requestManger的监听方法中,包括onStart、onStop、onDestroy。

RequestManger的生命周期监听方法调用,触发requestTracker对实际的request做出响应的处理。

流程并不是很复杂,这一章节,就省去流程图了。

以上是关于Glide 4.12 框架源码中的生命周期设计的主要内容,如果未能解决你的问题,请参考以下文章

Glide 4.12 框架源码中的生命周期设计

Glide 4.12 框架源码中的生命周期设计

Glide 4.12 框架源码中的生命周期设计

Glide 4.12图片框架之多级缓存源码设计分析

Glide 4.12图片框架之多级缓存源码设计分析

Glide 4.12图片框架之多级缓存源码设计分析