美文网首页
Glide 之生命周期管理

Glide 之生命周期管理

作者: 努力做一个最懒的程序员 | 来源:发表于2019-06-20 11:57 被阅读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 具体实现。

    相关文章

      网友评论

          本文标题:Glide 之生命周期管理

          本文链接:https://www.haomeiwen.com/subject/blydqctx.html