Glide解密-Android图片加载生命周期管理

1,051 阅读2分钟

在前面Glide鉴赏文章中,我们从整体架构和加载图片的完整流程对Glide进行了详细的分析,希望大家能对Glide有大概的理解,常言道:取其精华,去其糟粕,与其深陷在源码中,不如看看真正值得我们学习的是什么

Glide有个特性是可以依赖页面生命周期动态控制加载图片,比如在页面不可见时暂停加载,页面恢复时继续加载图片。其实现思想如下:

1 获取FragmentManager

在Glide.with流程中,调用RequestManagerRetriever#get这一步,根据传入Context类型和当前线程获取当前页面的FragmentManager

  • 若是在子线程或传入的Context为Application,最终调用RequestManagerRetriever#getApplicationManager,传入的是Application Context构建RequestManager,生命周期和App一致。
  • 若是在主线程,根据Context类型,获取到当前页面的FragmentManager,如下源码所示
  @NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

  @NonNull
  public RequestManager get(@NonNull Fragment fragment) {
    Preconditions.checkNotNull(
        fragment.getContext(),
        "You cannot start a load on a fragment before it is attached or after it is destroyed");
    if (Util.isOnBackgroundThread()) {
      return get(fragment.getContext().getApplicationContext());
    } else {
      FragmentManager fm = fragment.getChildFragmentManager();
      return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
    }
  }

2 构建SupportRequestManagerFragment

在上面获取到的FragmentManager中,先查找是否已经存在当前页面对应的SupportRequestManagerFragment,若不存在,则进行构建,并将其添加到上面获取到的FragmentManager中。对于SupportRequestManagerFragment,我们需要关注其内部这个对象ActivityFragmentLifecycle

ActivityFragmentLifecycle是用于添加依赖生命周期监听的对象。在SupportRequestManagerFragment构造时创建,只要实现了LifecycleListener接口的对象,都可以添加到弱引用的Set中,防止重复添加和内存泄漏。在SupportRequestManagerFragment的onStart,onStop,onDestroy会回调ActivityFragmentLifecycle对象的对应方法,从而对ActivityFragmentLifecycle内部添加的监听对象也进行遍历,调用各自的生命周期方法

public class SupportRequestManagerFragment extends Fragment {
  private final ActivityFragmentLifecycle lifecycle;
  private RequestManager requestManager;

  public SupportRequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }

  ActivityFragmentLifecycle getGlideLifecycle() {
    return lifecycle;
  }

  public void setRequestManager(@Nullable RequestManager requestManager) {
    this.requestManager = requestManager;
  }

  public RequestManager getRequestManager() {
    return requestManager;
  }

  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }
    // ...onStop, onDestory
}
class ActivityFragmentLifecycle implements Lifecycle {
  private final Set<LifecycleListener> lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
  private boolean isStarted;
  private boolean isDestroyed;

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

  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.remove(listener);
  }

  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }
    //...onStop,onDestroy
}

3 构建RequestManager和绑定监听

在构建了SupportRequestManagerFragment后,也是先从中获取RequestManager,即当前页面的请求管理器。若没有,则传入上面SupportRequestManagerFragment内部的ActivityFragmentLifecycle对象current.getGlideLifecycle(),构建出RequestManager,在RequestManager构造方法中,会将自身添加进传入的ActivityFragmentLifecycle对象里。如此,就将RequestManager和SupportRequestManagerFragment的生命周期方法绑定了

  // RequestManagerRetriever.java
  private RequestManager supportFragmentGet(@NonNull Context context, @NonNull FragmentManager fm,
      @Nullable Fragment parentHint, boolean isParentVisible) {
    SupportRequestManagerFragment current =
        getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
    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;
  }

以页面不可见时暂停加载为例,SupportRequestManagerFragment会执行onStop,流程如下图

public class RequestManager implements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> {
    public RequestManager(
      @NonNull Glide glide,
      @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode treeNode,
      @NonNull Context context) {
          //...
      }
    @Override
    public synchronized void onStop() {
      pauseRequests();
      targetTracker.onStop();
    }
}