Glide源码解析(一)

182 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

基本用法

Glide最基本的用法如下:

Glide.with(context)
     .load(url)
     .into(imageView)

本文就从这三个方法去学习Glide的源码。(挖个坑,以后补一下其他各种API的实现)

PS:本文基于4.13.2版本的Glide源码。

废话不多说直接开始!

with

首先with传入的是Context(具体分三种情况:Application、Fragment、Activity),返回的是RequestManager。暂时还不用了解这个RequestManager是什么,只要知道它是用来调用load()就可以了。

with的其中一个重载方法如下:

@NonNull
public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
}

正如上面所说,with传入的参数可以是Application、Fragment、Activity,所以with是有好几个对应的重载方法的。但是都跟上面这个大差不差,其实在这里还没有体现出差别。

接着看这个getRetriever的方法。Retriever的中文意思是猎犬,诶那我们肯定不能理解为猎犬是吧。我个人的理解是跟Fetcher的意思差不多,一个帮你到指定地方取某样东西回来的“人”。既然with的返回值是RequestManager,那“某样东西”自然就是RequestManager了。getRetriever很简单,如下:

@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    //省略
    return Glide.get(context).getRequestManagerRetriever();
}

Glide.get方法是构建一个Glide实例,getRequestManagerRetriever则是简单地返回一个Glide的内部变量,所以说重点就在Glide.get里面。

  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }
​
    return glide;
  }

可以很明显地看到,这是一个双重检查的懒汉式单例构建形式。换言之Glide的实例是一个单例。这个GeneratedAppGlideModule貌似是用来定制化Glide功能的,我也不大看得明白,就不管了hhh!

继续追踪checkAndInitializeGlide。里面再次检查了一下初始化情况,接着调用initializeGlide,我们直接看这个方法吧!

private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    Context applicationContext = context.getApplicationContext();
    //省略,GlideModule相关逻辑,无视无视。
​
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
    builder.setRequestManagerFactory(factory);
    
    //省略,GlideModule相关逻辑,无视无视。
    
    Glide glide = builder.build(applicationContext);
    
    //省略,GlideModule相关逻辑,无视无视。
    
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

除去GlideModule之外的逻辑大概分成三步:

  1. 获取RequestManager的Factory。
  2. 将Factory设给Glide的Builder并构建Glide实例。
  3. 向Application注册ComponentCallback(Glide实现)

第一步,获取RequestManager的Factory。判读是否有GlideModule,没有就传null。我们没用用到GlideModule那就应该是null。

第二步,重点在Builder的build方法中:

  @NonNull
  Glide build(@NonNull Context context) {
    //省略一大堆与配置相关的初始化代码,缓存、动画、bitmap复用池等等
​
    GlideExperiments experiments = glideExperimentsBuilder.build();
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory, experiments);
​
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        experiments);
  }

GlideExperiments我看了下注释,貌似是用来跟踪实验性API过程的东西(也就是说不用管它)。

终于到了构建RequestManagerRetriever了,继续跟踪。

  public RequestManagerRetriever(
      @Nullable RequestManagerFactory factory, GlideExperiments experiments) {
    this.factory = factory != null ? factory : DEFAULT_FACTORY;
    handler = new Handler(Looper.getMainLooper(), this);
​
    frameWaiter = buildFrameWaiter(experiments);
  }

由于我们传入的Factory是null,所以这里将会使用DEFAULT_FACTORY。大胆猜测一下,RequestManagerRetriever获取RequestManager的方式就是从这个DEFAULT_FACTORY生产出来的。

接着还创建了一个handler用于接收一些指令,与后面感知生命周期的逻辑有关。

最后还build了一个FrameWaiter,因为传入的是GlideExperiments,所以应该是跟实验性API有关的,这里也不管了。

上面这段代码最重要的地方就是这个DEFAULT_FACTORY,继续看看是啥玩意。

private static final RequestManagerFactory DEFAULT_FACTORY =
      new RequestManagerFactory() {
        @NonNull
        @Override
        public RequestManager build(
            @NonNull Glide glide,
            @NonNull Lifecycle lifecycle,
            @NonNull RequestManagerTreeNode requestManagerTreeNode,
            @NonNull Context context) {
          return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
        }
      };

可以看出来,DEFAULT_FACTORY就是RequestManagerFactory的一个匿名实现,build方法返回一个RequestManager。

这里用图的方式复习一下:

sequenceDiagram
Glide->>Glide:with()
Glide->>Glide:getRetriever()
Glide->>Glide:get()
Glide->>GlideBuilder:new
GlideBuilder->>GlideBuilder:build()
GlideBuilder->>RequestManagerRetriever:new
RequestManagerRetriever->>RequestManagerRetriever:DEFAULT_FACTORY
RequestManagerRetriever->>GlideBuilder:requestManagerRetriever()
GlideBuilder->>Glide:glide
Glide->>Glide:getRequestManagerRetriever()

这时候RequestManagerRetriever已经构造出来了,让我们回头再看回with方法,这里再贴一遍代码,免得往上翻了。

@NonNull
public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
}

既然getRetriever已经构建好RequestManagerRetriever了,那就看看RequestManagerRetriever.get吧!

  @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
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null)       {//④
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
​
    return getApplicationManager(context);//⑤
  }

get有好几个重载方法,上面贴出来的则是负责根据Context的具体类型调用不同的get方法。

首先是①处判断,在主线程调用并且传入的Context为非Application。

然后是②处判断,传入Context是FragmentActivity。

接着是③处判断,传入Context为Activity。

跟着是④处判断,传入的Context是ContextWrapper并且Application不为空。

最后是⑤处判断,以上判断都不符合。

其中FragmentActivity和Activity的区别判断应该是为了向低版本兼容,这里就只讨论Activity的情况。

如果传入的Context为Activity,对应的get如下:

  @NonNull
  public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else if (activity instanceof FragmentActivity) {
      return get((FragmentActivity) activity);
    } else {//①
      assertNotDestroyed(activity);
      frameWaiter.registerSelf(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(activity, fm, null, isActivityVisible(activity));
    }
  }

重点看①处后的代码,一行行来看。

assertNotDestroyed用于判读传入的Acitivity是否已销毁,已销毁则抛出异常。

framWaiter忽略。

获取FragmentManager。

调用fragmentGet方法:

@NonNull
  private RequestManager fragmentGet(
      @NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible
  ) {
    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);
      if (isParentVisible) {
        requestManager.onStart();
      }
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

首先调用了getRequestManagerFragment获取了一个RequestManagerFragment。RequestManagerFragment实际上就是一个Fragment的子类。它的用途就是感知Activity的生命周期。通过目标Activity的FragmentManager构建一个无界面的Fragment,并且由于Fragment与Activity的生命周期是同步的,所以就能感知目标Activity的生命周期变化。刚刚上面那个RequestManagerRetriever里面的handle就是用来接受移除这个Fragment的指令的。

通过观察不同的RequestManager.get的重载方法,发现不管传入的是Activity还是Fragment,最终都是通过添加一个无界面的Fragment去感知生命周期的。

由于第一次创建这个Fragment,所以不能获取到RequestManager。代码走到了获取RequestManager里。可以看到是通过调用RequestManagerFactory.build来构建的,从之前的分析我们知道这个Factory就是DEFAULT_FACTORY。

后半部分的流程也用图的方式复习一下:

sequenceDiagram
RequestManagerRetriever->>RequestManagerRetriever:get()
RequestManagerRetriever->>RequestManagerRetriever:fragmentGet()
RequestManagerRetriever->>RequestManagerFragment:getRequestManagerFragment()
RequestManagerFragment->>RequestManagerRetriever:fragment
RequestManagerRetriever->>RequestManagerFactory:build()
RequestManagerFactory->>RequestManagerRetriever:requestManager

至此,with的工作就已经完成了,我们也获得了RequestManager。下一篇我们再来分析RequestManager以及它的load方法。