Glide 之生命周期管理

2019-06-20  本文已影响0人  努力做一个最懒的程序员

Glide 中运用到的优秀技术有很多值得我们深入学习,这篇文章就来介绍一下 Glide 的生命周期是如何与 Activity、Fragment 进行绑定的。

一、with()入参分类

Glide.with(arg)可以接收 ActivityFragmentActivityFragmentv4.FragmentContextView 六种类型,然后通过 RequestManagerRetriever 获取 RequestManager。

1.Context、View

这两种方法都是先确定其类型,如果它的 Context 不属于 Activity、FragmentActivity、Fragment、v4.Fragment 则生命周期与应用同步,无需处理。

public RequestManager get(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);
  }

public RequestManager get(View view) {
    if (Util.isOnBackgroundThread()) {
      return get(view.getContext().getApplicationContext());
    }

    Preconditions.checkNotNull(view);
    Preconditions.checkNotNull(view.getContext(),
        "Unable to obtain a request manager for a view without a Context");
    Activity activity = findActivity(view.getContext());
    // The view might be somewhere else, like a service.
    if (activity == null) {
      return get(view.getContext().getApplicationContext());
    }

    // Support Fragments.
    // Although the user might have non-support Fragments attached to FragmentActivity, searching
    // for non-support Fragments is so expensive pre O and that should be rare enough that we
    // prefer to just fall back to the Activity directly.
    if (activity instanceof FragmentActivity) {
      Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
      return fragment != null ? get(fragment) : get(activity);
    }

    // Standard Fragments.
    android.app.Fragment fragment = findFragment(view, activity);
    if (fragment == null) {
      return get(activity);
    }
    return get(fragment);
  }

2.FragmentActivity、Activity

这两个只有 FragmentManager 不同,其他流程都相同。

public RequestManager get(FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      // SupportFragmentManager
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(activity, fm, null /*parentHint*/);
    }
  }

  public RequestManager get(Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      // FragmentManager
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(activity, fm, null /*parentHint*/);
    }
  }

3.Fragment、v4.Fragment

可以看到这两种类型在调用 ***fragmentGet()时多传了一个 fragment。而 fragmentGet 与 supportFragmentGet 没有太大区别,

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
  public RequestManager get(android.app.Fragment fragment) {
    if (fragment.getActivity() == null) {
      throw new IllegalArgumentException(
          "You cannot start a load on a fragment before it is attached");
    }
    if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
      return get(fragment.getActivity().getApplicationContext());
    } else {
      android.app.FragmentManager fm = fragment.getChildFragmentManager();
      // fragmentGet
      return fragmentGet(fragment.getActivity(), fm, fragment);
    }
  }

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

二、fragmentGet() 与 supportFragmentGet()

fragmentGet()supportFragmentGet() 两个函数原理其实相同,所以这里就 fragmentGet 来进行讲解。

这个函数中有两个类是实现生命周期管理的核心 RequestManagerFragment 和 RequestManager。

  private RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
      android.app.Fragment parentHint) {
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
    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;
  }

三、RequestManager 与 RequestManagerFragment 的合作

RequestManager 实现了 LifecycleListener 接口,用于管理 Glide 的请求,可以同步 Activity、Fragment 生命周期进行启动、停止、重启操作。

RequestManagerFragment作为一个无视图的 Fragment 可以和当前的 Activity 或者 Fragment 进行绑定,这样在自己的生命周期就可以同步监听到它们的生命周期,通过 ActivityFragmentLifecycle 将 RequestManager 进行生命周期同步。

childRequestManagerFragments 用于存放当前 Activity 下所有的 RequestManagerFragment;RequestManagerTreeNode 存储了此 RequestManagerFragment 的父元素所对应的一组Fragment。这样层层嵌套,保证了上层变动后下层可以实时更新。

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
  RequestManagerFragment getRequestManagerFragment(
      final android.app.FragmentManager fm, android.app.Fragment parentHint) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

getRequestManagerFragment 会从 FragmentManager 中查找当前 Activity 或者 Fragment 是否已经创建过标记为 FRAGMENT_TAG 的 RequestManagerFragment,如果没有找到会将其创建并添加到 FragmentManager 中。

可以看到新创建的 RequestManagerFragment 刚刚放入 pendingRequestManagerFragments,但是紧接着又调用 handler 将其移除了,这是为了防止同一个界面创建多个 RequestManagerFragment。

总结

所以 Glide 管理生命周期的整体流程就是先创建一个无视图的 Fragment,并同时创建这个 Fragment 的 ActivityFragmentLifeCycle 对象,当这个 Framgent 的生命周期发生变化时会调用 ActivityFragmentLifeCycle 使其中的 RequestManager 做出对应处理,由 RequestTracker 具体实现。

上一篇 下一篇

猜你喜欢

热点阅读