深入理解Glide(一)with(xxx)

文章基于Glide 4.9.0

Glide.with(xxx)

Glide.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);
  }
  
  @SuppressWarnings("deprecation")
  @NonNull
  public static RequestManager with(@NonNull android.app.Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
  }
  
  @NonNull
  public static RequestManager with(@NonNull View view) {
    return getRetriever(view.getContext()).get(view);
  }

可以看到返回的都是getRetriever(Context context).get(xx);

我们先看getRetriever(Context context)

 @NonNull
  private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    // Context could be null for other reasons (ie the user passes in null), but in practice it will
    // only occur due to errors with the Fragment lifecycle.
    Preconditions.checkNotNull(
        context,
        "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
            + "returns null (which usually occurs when getActivity() is called before the Fragment "
            + "is attached or after the Fragment is destroyed).");
    return Glide.get(context).getRequestManagerRetriever();
  }

可以看到返回RequestManagerRetriever这个对象。至于Preconditions.checkNotNull(context,xxx)方法很简单,就不列举源码了,意思就是如果context如果是空,就报空指针,msg是xxx。

然后我们来看Glide.get(context).getRequestManagerRetriever();

@NonNull
  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context);
        }
      }
    }

    return glide;
  }

可以看到是用同步锁的方式返回了Glide对象,同时会做一些初始化的工作,初始化的工作我们先跳过,现在可以简单地理解为,利用Glide.Builder做了初始化并且实例化,后续我们再来解释这块(其实对Glide的一些配置就是在这里做的,比如缓存策略,加载方式等等)。

然后看Glide的getRequestManagerRetriever()方法

    @NonNull
  public RequestManagerRetriever getRequestManagerRetriever() {
    return requestManagerRetriever;
  }

可以看到就是RequestManagerRetriever这个对象的实例。简单看下RequestManagerRetriever

public class RequestManagerRetriever implements Handler.Callback 

发现他是实现 Handler.Callback ,大胆猜测就是通过handler来实现异步加载然后回调到主线程。

接下来再看看getRetriever(Context context).get(xxx),其实就是RequestManagerRetriever的get(xxx)

@NonNull
  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);
  }
  
  
  @NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
    ···
  }
  
  @NonNull
  public RequestManager get(@NonNull Fragment fragment) {
    ···
  }
  
  
  @SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull Activity activity) {
    ···
  }

  @SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull View view) {
   ···
  }

为了方便大家看他们直接关系,我把一些get(xxx)的内部实现省略了,可以看到会根据不同情况返回RequestManager对象。同时注意分为了两种情况,一种是Application类的context,一种不是。

我们先看非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());
      }

对比下他们的内部实现

@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.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();
      return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
    }
  }

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

可以发现,如果不是在主线程,get(application)方法,主线程是get(@NonNull FragmentActivity activity) 和get(@NonNull Fragment fragment)都是返回supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());。而get(@NonNull Activity activity)方法其实已经过期,我们也简单的了解下。它返回的是fragmentGet(
activity, fm, /parentHint=/ null, isActivityVisible(activity));

对比

 @Deprecated
  @NonNull
  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;
  }
  
  
  @NonNull
  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) {
      // 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;
  }

可以发现都是通过SupportRequestManagerFragment.getRequestManager()返回一个RequestManager对象。我们来看这个方法

public class SupportRequestManagerFragment extends Fragment {

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

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

 @Nullable
  public RequestManager getRequestManager() {
    return requestManager;
  }
  
  public void setRequestManager(@Nullable RequestManager requestManager) {
    this.requestManager = requestManager;
  }
  
  @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();
  }
  
  ···其他省略代码
}

直接返回一个requestManager,而requestManager是通过RequestManagerFactory在initializeGlide时创建的。同时我们发现正是通过这种方式来关联相对应的生命周期。简单看看RequestManager是什么。

public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
}

再来看作为application时的情况getApplicationManager(context);

@NonNull
  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) {
          // Normally pause/resume is taken care of by the fragment we add to the fragment or
          // activity. However, in this case since the manager attached to the application will not
          // receive lifecycle events, we must force the manager to start resumed using
          // ApplicationLifecycle.

          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context.getApplicationContext());
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }

    return applicationManager;
  }

可以看到直接使用factory创建了一个RequestManager。

至此真像大白。

总结

Glide.with(xxx)我们可以简单理解为如下几部。

  • 初始化Glide
  • 创建RequestManagerRetriever对象
  • 使用RequestManagerRetriever的get(xxx)方法获取具体的RequestManager
    • Fragment,Activity,和FragmentActivity不在后台线程时使用SupportRequestManagerFragment来创建RequestManager。生命周期就是其相关的生命周期
      • SupportRequestManagerFragment继承Fragment,Glide之所以加载图片可以关联生命周期,其实就是用的SupportRequestManagerFragment的生命周期
    • 其他情况使用默认的方式来创建RequestManager,声明周期和application一样
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值