Glide(1) Lifecycle Binding

Posted by luke_barnes on Thu, 18 Jun 2020 18:09:43 +0200

Glide.with(FragmentActivity activity)
// RequestManager with(FragmentActivity activity)
public static RequestManager with(Activity activity) {
    return getRetriever(activity).get(activity);
}
public RequestManager get(Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      // Get the Fragment Manager of the current Activity,
      // Subsequently used for new Fragments and bound to the current FragmentManager to obtain the life cycle of the Fragment (synchronization Activity life cycle)
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(activity, fm, null /*parentHint*/);
    }
  }
  • 1.2 See RequestManagerFragment here
private RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
      android.app.Fragment parentHint) {
    // a. Bind RequestManager Fragment to Fragment Manager to synchronize RequestManager Fragment lifecycle activities
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      // TODO(b/27524013): Factor out this Glide.get() call.
      Glide glide = Glide.get(context);
      requestManager =
          // b. Get an instance of RequestManager and give the current RequestManager Fragment
          factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode());
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }
  • 1.3 Bind RequestManager Fragments to FragmentManager, and RequestManager Fragments currently have their life cycle and see how to implement it
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
  RequestManagerFragment getRequestManagerFragment(
      final android.app.FragmentManager fm, android.app.Fragment parentHint) {
     //a. Get RequestManagerFragment instances based on TAG id
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      // b. If a does not get an instance, get it from the map in memory
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        // c. None of the above a or B fetches an instance, then the last new one is put into the memory map
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        pendingRequestManagerFragments.put(fm, current);
        // Fragments are bound to FragmentManager, so RequestManager Fragments have a life cycle
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }
  • 1.4 Reference to action b in step 1.2 above causes RequestManager in RequestManager Fragment, which adds itself to Lifecycle in construction
RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory) {
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;

    ...
    if (Util.isOnBackgroundThread()) { // Non-main Thread
      mainHandler.post(addSelfToLifecycle);
    } else { // Main Thread
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
  }

  private final Runnable addSelfToLifecycle = new Runnable() {
    @Override
    public void run() {
      lifecycle.addListener(RequestManager.this);
    }
  };
  • 2.1 Transfer of Fragment lifecycle
public RequestManagerFragment() {
    // Initialize ActivityFragmentLifecycle at construction time
    this(new ActivityFragmentLifecycle());
}

@SuppressLint("ValidFragment")
RequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
}

// Here is the lifecycle overview
 @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();
  }
  • 2.2 Callback all lifecycle interfaces
    • RequestManager Fragment calls back all registered RequestManagers
@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();
    }
  }
}

summary

  • 1. Bind an empty RequestManager Fragment to synchronize the Activity lifecycle by getting the Fragment Manager of the Activity
  • 2. Initialize LifecycleListener in RequestManagerFragment
  • 3. Initialize RequestManager Fragment, colleague initialize RequestManager, and register with Lifecycle Listener
  • 4. When an activity triggers a life cycle, calls back Fragment and passes it to Lifecycle Listener, which calls back all RequestManager s registered with it
  • All in all, the new decoupling skills.Time Series Graph Offered

Topics: Fragment Android