Glide4.9.0 任务生命周期管理

一、概述

众所周知,Glide会根据一定的条件自动管理任务的开始和暂停,那么这个具体条件是什么呢?这篇文章将会探索其中的秘密。主要根据调用Glide.with(T)的不同分为2种情况。1、可以找到T对应的Activity或者android.app.FragmentAndroid3.0版本之前是android.support.v4.app.Fragment或者FragmentActivity),使用ActivityFragmentLifecycle。2、找不到就使用ApplicationLifecycle

下面是ApplicationLifecycleActivityFragmentLifecycle以及LifecycleLIstener的类图结构。
在这里插入图片描述
在这里插入图片描述
我们可以清楚的看到,ApplicationLifecycle并没有定义onStartonStoponDestroy等方法,仅仅是在addListener的时候直接调用LifecycleListener#onStart。这里很容易理解,因为Application并不像Activity具有那么多生命周期回调。所以现在我们可以大概了解,Glide的生命周期管理是通过这2个类实现的,下面分开详述。

二、ActivityFragmentLifecycle

根据T的类型,Glide#with(T) 会调用到合适的RequestManagerRetriever#get(T)。这里有很多个重载方法,主要思想是大同小异,我们只需要分析其中一个即可。
在这里插入图片描述

//RequestManagerRetriever.java
@SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull Activity activity) {
  	//不是主线程,会使用ApplicationLifecycle
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      //这个方法就会生成RequestManagerFragment,并且持有一个RequestManager并返回。
      return fragmentGet(
          activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }
  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = getRequestManagerFragment(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
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }
  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
      	//RequestManagerFragment构造函数会创建ActivityFragmentLifecycle
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          //当前界面可见,直接调用onStart()
          current.getGlideLifecycle().onStart();
        }
        //预防onSaveInstanceState()之后调用commitAllowingStateLoss()
        //这时候系统由于系统约束(而不是正常的应用程序行为)而破坏了Activity
        //add动作将会丢失,所以通过pendingRequestManagerFragments备份。
        //通过handler延时处理删除。
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

通过工厂方法最后会调用这里,创建RequesetManager,这里需要注意的是lifecycle这个形参的来源,这里是来源于current.getGlideLifecycle()。其实就是RequestManagerFragment中的ActivityFragmentLifecycle实例变量。

//RequestManager.java
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;
	//这里的factory默认值是DefaultConnectivityMonitorFactory,根据onStart,onStop注册,反注册一个
	//ConnectivityManager.CONNECTIVITY_ACTION的广播
    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

    // If we're the application level request manager, we may be created on a background thread.
    // In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
    // issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
    // This should be entirely safe.
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      //添加自身。
      lifecycle.addListener(this);
    }
    //
    lifecycle.addListener(connectivityMonitor);

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

    glide.registerRequestManager(this);
  }
最后我们看到RequestManagerFragment的实现就知道了,整个的任务生命周期逻辑是RequestManagerFragment #onStart->ActivityFragmentLifecycle#onStart->LifecycleListener#onStart。依据Fragment的生命周期回调,以及网络连接广播实现。
//RequestManagerFragment.java
public class RequestManagerFragment extends Fragment {
  @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();
  }
}

三、ApplicationLifecycle

//RequestManagerRetriever.java
@NonNull
  private RequestManager getApplicationManager(@NonNull Context context) {
  	//使用了DCL单例模式
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          // Normally pause/resume is taken care of by the fragment we add to the fragment or
          // activity. However, in this case since the manager attached to the application will not
          // receive lifecycle events, we must force the manager to start resumed using
          // ApplicationLifecycle.

          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context.getApplicationContext());
          //可以看到,applicationManager是实例对象,而且这里使用的ApplicationLifecycle
          //并没有其他地方可以引用到,结合上面提到创建的RequestManager的时候会调用
          //Lifecycle#addListener,添加进去的分别是RequestManager自身以及
          //DefaultConnectivityMonitor实例对象。
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }

    return applicationManager;
  }

下面可以看看到ApplicationLifecycle#addListener会直接调用LifecycleListener#onStart

//ApplicationLifecycle.java
class ApplicationLifecycle implements Lifecycle {
  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    listener.onStart();
  }

  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
    // Do nothing.
  }
}

可以看看RequestManager#onStartConnectivityMonitor#onStart做了什么。

//RequestManager.java
@Override
  public synchronized void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }
//DefaultConnectivityMonitor.java
@Override
  public void onStart() {
    register();
  }
  private void register() {
    if (isRegistered) {
      return;
    }

    // Initialize isConnected.
    isConnected = isConnected(context);
    try {
      // See #1405
      context.registerReceiver(connectivityReceiver,
          new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
      isRegistered = true;
    } catch (SecurityException e) {
      // See #1417, registering the receiver can throw SecurityException.
      if (Log.isLoggable(TAG, Log.WARN)) {
        Log.w(TAG, "Failed to register", e);
      }
    }
  }
看到这里,我们可以清晰知道,这种情况下的任务生命周期管理逻辑是依据创建applicationManager时直接调用,以及网络连接广播变化实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值