Glide生命周期控制原理

Glide生命周期的原理

Glide.with有很多重载方法:

@NonNull
public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
}
@NonNull
 public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(@NonNull android.app.Fragment fragment) {
 return getRetriever(fragment.getActivity()).get(fragment);
}

其中getRetriever方法是获取RequestManagerRetriever对象,然后调用Get方法。RequestManagerRetriever的get方法看起来有多个重载,参数为context、fragment、activity、view等但实际上只有两种区别,一种是Application类型的对象时,另一种是非Application的对象。

public RequestManager get(@NonNull Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        return get((Activity) context);
      } else if (context instanceof ContextWrapper) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
    return getApplicationManager(context);
}

参数是Application类型的对象时,通过getApplicationManager返回RequestManager对象,getApplicationManager中绑定application的生命周期,当程序结束时,glide生命周期结束。

private RequestManager getApplicationManager(@NonNull Context context) {
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          Glide glide = Glide.get(context.getApplicationContext());
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }
    return applicationManager;
    }

ApplicationLifecycle只在addListener时调用onStart方法。

非Application类型对象,传入的对象不同,但操作的流程是一样的。通过向Activity添加一个无UI Fragment,来监听Activity的生命周期,然后进行管控。
为什么要添加一个Fragment呢?原因很简单,当我们下载一张图片时,如果当前Activity已经销毁了,那么我们继续下载显然是不合理。因此Glide需要监听Activity的生命周期,但是又没有办法直接获取Activity的生命周期,所以Glide采用添加Fragment的小技巧。我们知道Fragment的生命周期和Activity生命周期是同步的,因此可以通过监听Fragment的生命周期来监听Activity。这时Glide就可以获取生命周期的事件并且处理加载的流程了。
Fragment和v4.Fragment的不同导致方法最终分别调用了fragmentGetsupportFragmentGet,这两个方法操作都是一样的,我们直接看一看fragmentGet:

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 =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
}

getRequestManagerFragment是获取Fragment的过程,获取到之后判断绑定的RequestManager是否为空,为空则重新创建绑定。注意RequestManager实现了LifecycleListener,是生命周期环境重要的一项。我们后面来看 现在先来看下真正添加Fragment的过程:

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) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
}

getRequestManagerFragment方法会去判断FRAGMENT_TAG标志位的Fragment存不存在,如果存在就返回当前RequestManagerFragment,不存在则从pendingRequestManagerFragments去获取。如果获取不为空,说明当前Fragment真正被添加的过程中,返回当前Fragment不用再次添加,如果为空说明第一次添加,则new一个Fragment添加到Activity。其中pendingRequestManagerFragments添加又通过Handler去删除是为了防止重复添加。

RequestManagerFragment包含了ActivityFragmentLifecycle对象,在构造方法中初始化:

public RequestManagerFragment() {
   this(new ActivityFragmentLifecycle());
   }
   @VisibleForTesting
   @SuppressLint("ValidFragment")
  RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
   this.lifecycle = lifecycle;
 }
}

RequestManagerFragment生命周期方法中回调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();
}

ActivityFragmentLifecycle生命周期回调的实现:

public void addListener(@NonNull LifecycleListener listener) {
   lifecycleListeners.add(listener);
  if (isDestroyed) {
      listener.onDestroy();
} else if (isStarted) {
      listener.onStart();
} else {
      listener.onStop();
 }
}

void onStop() {
   isStarted = false;
   for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
     lifecycleListener.onStop();
   }
}

可以看到ActivityFragmentLifecycle的回调代码会遍历lifecycleListeners,然后调用其对应的回调方法,而lifecycleListeners是通过addListener添加的。
RequestManager实现了LifecycleListener接口,在RequestManagerFactory.Build时会拿到当前Fragment的生命周期管理属性 current.getGlideLifecycle():

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

build方法实际上就是获取RequestManager实例的方法:

RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    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);
  }

创建时将自身关联到lifecycleListeners中,当Fragment生命周期方法调用时,RequestManager对应的方法也会调用:

public synchronized void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }

public void pauseRequests() {
    isPaused = true;
    for (Request request : Util.getSnapshot(requests)) {
      if (request.isRunning()) {
        request.clear();
        pendingRequests.add(request);
      }
    }
  }

pauseRequestsresumeRequests是控制请求加载还是暂停的方法,内部调用的是RequestTracker对应的pauseRequests方法,进而控制每一个Request请求。

总结:

1.Glide生命周期管理原理是通过新增Fragment监听到Activity的生命周期,然后做相关处理。
2.流程为:Fragment生命周期 ->ActivityFragmentLifecycle相关生命周期方法->RequestManager相关生命周期方法->RequestTracker请求管控->Requset控制

你可能感兴趣的:(Glide生命周期控制原理)