Glide源码分析一

Glide 的 with 源码分析

以下分析的所有源码,都只是部分源码,只为了总体流程分析。

Glide 显示网络图片最简单的代码如下:

Glide.with(this).load(url).into(mImageView);

在这里,我先展示一张整体的加载流程图:

接下来,我们一步步分析 with 的源码。

  // 传入View 
public static RequestManager with(@NonNull View view) {
  return getRetriever(view.getContext()).get(view);
}

  // 传入 Fragment
public static RequestManager with(@NonNull Fragment fragment) {
  return getRetriever(fragment.getContext()).get(fragment);
}

  // 传入 FragmentActivity
public static RequestManager with(@NonNull FragmentActivity activity) {
  return getRetriever(activity).get(activity);
}

  // 传入 Activity
public static RequestManager with(@NonNull Activity activity) {
  return getRetriever(activity).get(activity);
}

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

共有 5 个重载的 with 方法,分别在不同的场景使用,但是所有的方法都会调用 getRetriever 方法。

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

接下来,重点分析 get 方法。

public static Glide get(@NonNull Context context) {
  if (glide == null) {
      // 获取Glide注解自动生成的一个Module配置器
    GeneratedAppGlideModule annotationGeneratedModule =
        getAnnotationGeneratedGlideModules(context.getApplicationContext());
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context, annotationGeneratedModule);
      }
    }
  }

  return glide;
}

该方法是一个双检锁单例模式,首先调用 getAnnotationGeneratedGlideModules 方法来获取 Glide 注解自动生成的一个配置器类,主要是利用反射机制来构建一个配置类实例,这个类是在注解生成器里面生成的。

private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules(Context context) {
  GeneratedAppGlideModule result = null;
    Class<GeneratedAppGlideModule> clazz =
        (Class<GeneratedAppGlideModule>)
            Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
    result =
        clazz.getDeclaredConstructor(Context.class).newInstance(context.getApplicationContext());
  return result;
}

然后调用 checkAndInitializeGlide 来检查并初始化 Glide

private static void checkAndInitializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  isInitializing = true;
  initializeGlide(context, generatedAppGlideModule);
  isInitializing = false;
}

重点在 initializeGlide 方法。

private static void initializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    // 创建了一个构建器对象 GlideBuilder ,默认的一些参数和配置
  initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

接着又调用了一个重载的 initializeGlide 方法,这才是真正初始化 Glide 的方法。

private static void initializeGlide(
    @NonNull Context context,
    @NonNull GlideBuilder builder,
    @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
  Context applicationContext = context.getApplicationContext();
  List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
  // 1.如果没有注解生成器,或者开启了 Manifest 的检索
  if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
    manifestModules = new ManifestParser(applicationContext).parse();
  }

  // 2.编译时自动生成的类中,包含了需要排除的GlideModule,逐个将其移除
  if (annotationGeneratedModule != null
      && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
    Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
    Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
    while (iterator.hasNext()) {
      com.bumptech.glide.module.GlideModule current = iterator.next();
      if (!excludedModuleClasses.contains(current.getClass())) {
        continue;
      }
      iterator.remove();
    }
  }

  RequestManagerRetriever.RequestManagerFactory factory =
      annotationGeneratedModule != null
          ? annotationGeneratedModule.getRequestManagerFactory()
          : null;
  builder.setRequestManagerFactory(factory);

  // 3.下面的代码是回调 Module 的 applyOptions 方法来配置属性
  // 用户自定义配置的属性就生效了
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    module.applyOptions(applicationContext, builder);
  }
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.applyOptions(applicationContext, builder);
  }

  // 4.实例化 Glide
  Glide glide = builder.build(applicationContext);

  // 5.下面的代码是回调 Module 的  registerComponents 方法来注册组件
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.registerComponents(applicationContext, glide, glide.registry);
  }
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
  }
  applicationContext.registerComponentCallbacks(glide);
  // 6.赋值给单例对象
  Glide.glide = glide;
}

该初始化方法主要做的工作如下:

  1. 检索 Manifest 文件配置的 GlideModule 。
  2. 移除重复的 GlideModule 。
  3. 回调 GlideModule 的 applyOptions 方法来配置自定义的属性。
  4. 调用 build 方法来构建 Glide 实例。
  5. 回调 GlideModule 的 registerComponents 方法来注册组件。
  6. 把 glide 实例赋值给单例对象。

在第 4 步中会构建 Glide 实例,整个框架非常重要的初始化内容都在这里实现,下面我们重点来看一下这个 build 方法。

Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
        // 创建资源加载请求器,是一个线程池,用于加载源数据(URL等)
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }

    if (diskCacheExecutor == null) {
        // 创建磁盘缓存请求器,是一个线程池
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }

    if (animationExecutor == null) {
        // 创建动画加载请求器,是一个线程池
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }

    if (memorySizeCalculator == null) {
        // 内存计算器
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }

    if (connectivityMonitorFactory == null) {
        // 网络状态检测器
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

    if (bitmapPool == null) {
        // 创建 bitmap 资源缓存池,用于资源的回收和缓存,避免由于大量创建和回收 bitmap 导致内存抖动
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }

    // 数组资源缓存池
    if (arrayPool == null) {
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    if (memoryCache == null) {
        // 内存缓存,用于缓存加载完成和显示的图片数据资源
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
        // 磁盘缓存器,默认为 APP 内部私密目录
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
        // 创建图片加载引擎,用于执行图片加载请求驱动,注意传入的参数
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

    // 构建一个请求监听器列表
    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

    // 请求索引器
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    // 创建 Glide,注意传入的参数
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled,
        isImageDecoderEnabledForBitmaps,
        hardwareBitmapFdLimit);
  }
}

这个方法主要是实例化一些对象,真正实例化 Glide 对象是最后面的new Glide() ,那么我们继续分析 Glide 的构造方法。由于该方法代码量非常多,故省略大量代码,只显示核心逻辑。

Glide(
    @NonNull Context context,
    @NonNull Engine engine,
    @NonNull MemoryCache memoryCache,
    @NonNull BitmapPool bitmapPool,
    @NonNull ArrayPool arrayPool,
    @NonNull RequestManagerRetriever requestManagerRetriever,
    @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
    int logLevel,
    @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
    @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
    @NonNull List<RequestListener<Object>> defaultRequestListeners,
    boolean isLoggingRequestOriginsEnabled,
    boolean isImageDecoderEnabledForBitmaps,
    int hardwareBitmapFdLimit) {

    // 赋值
  this.engine = engine;
  this.bitmapPool = bitmapPool;
  this.arrayPool = arrayPool;
  this.memoryCache = memoryCache;
  this.requestManagerRetriever = requestManagerRetriever;
  this.connectivityMonitorFactory = connectivityMonitorFactory;
  this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;

  final Resources resources = context.getResources();

  // 新建注册器
  registry = new Registry();
  registry.register(new DefaultImageHeaderParser());
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
    registry.register(new ExifInterfaceImageHeaderParser());
  }

  List<ImageHeaderParser> imageHeaderParsers = registry.getImageHeaderParsers();

  // 创建解码器
  ByteBufferGifDecoder byteBufferGifDecoder =
      new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);
  ResourceDecoder<ParcelFileDescriptor, Bitmap> parcelFileDescriptorVideoDecoder =
      VideoDecoder.parcel(bitmapPool);

  ResourceDecoder<ByteBuffer, Bitmap> byteBufferBitmapDecoder;
  ResourceDecoder<InputStream, Bitmap> streamBitmapDecoder;
  if (isImageDecoderEnabledForBitmaps && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    streamBitmapDecoder = new InputStreamBitmapImageDecoderResourceDecoder();
    byteBufferBitmapDecoder = new ByteBufferBitmapImageDecoderResourceDecoder();
  } else {
    Downsampler downsampler =
        new Downsampler(
            registry.getImageHeaderParsers(),
            resources.getDisplayMetrics(),
            bitmapPool,
            arrayPool);
    byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
    streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
  }

  ResourceDrawableDecoder resourceDrawableDecoder = new ResourceDrawableDecoder(context);
  // 创建数据转换器
  ResourceLoader.StreamFactory resourceLoaderStreamFactory =
      new ResourceLoader.StreamFactory(resources);
  ResourceLoader.UriFactory resourceLoaderUriFactory = new ResourceLoader.UriFactory(resources);
  ResourceLoader.FileDescriptorFactory resourceLoaderFileDescriptorFactory =
      new ResourceLoader.FileDescriptorFactory(resources);
  ResourceLoader.AssetFileDescriptorFactory resourceLoaderAssetFileDescriptorFactory =
      new ResourceLoader.AssetFileDescriptorFactory(resources);
  BitmapEncoder bitmapEncoder = new BitmapEncoder(arrayPool);

  // 创建转码器
  BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();
  GifDrawableBytesTranscoder gifDrawableBytesTranscoder = new GifDrawableBytesTranscoder();

  ContentResolver contentResolver = context.getContentResolver();

  // 注册各个类型的解码器和编码器
  registry
      .append(ByteBuffer.class, new ByteBufferEncoder())
      .append(InputStream.class, new StreamEncoder(arrayPool))

      // 这里省略大量注册代码

      .register(
          Drawable.class,
          byte[].class,
          new DrawableBytesTranscoder(
              bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder))
      .register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder);

  // 创建图片显示目标对象工厂
  ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
  // 创建 GlideContext 对象,注意传入的参数
  glideContext =
      new GlideContext(
          context,
          arrayPool,
          registry,
          imageViewTargetFactory,
          defaultRequestOptionsFactory,
          defaultTransitionOptions,
          defaultRequestListeners,
          engine,
          isLoggingRequestOriginsEnabled,
          logLevel);
}

该方法主要是初始化模型转换器、解码器、转码器和编码器,并对各种类型在注册表一一进行注册。

Glide 的加载流程可以概括为以下流程:

model(数据源)-->data(转换数据)-->decode(解码)-->transformed(缩放)-->transcoded(转码)-->encoded(编码保存到本地)

这个流程非常重要,后面的源码分析就是一步步对流程的每个步骤进行分析。注册表里注册的各种模型转换器、解码器、转码器和编码器,都分别在各个步骤起作用。

到这里,Glideget 方法终于分析完成,那么让我们回到 getRetriever 方法,在实例化 Glide后,会调用 getRequestManagerRetriever 方法来获取 RequestManagerRetriever 对象。

public RequestManagerRetriever getRequestManagerRetriever() {
  return requestManagerRetriever;
} 

回到最开始的 with 方法可知,后面会根据不会场景来调用 RequestManagerRetriever 的重载 get 方法。接下来我们分析最常用的入参为 Activity 的重载方法。

public RequestManager get(@NonNull Activity activity) {
    // 是否后台线程
  if (Util.isOnBackgroundThread()) {
      // 获取 getApplicationContext,调用重载的 get 方法
    return get(activity.getApplicationContext());
  } else {
    assertNotDestroyed(activity);
    android.app.FragmentManager fm = activity.getFragmentManager();
    return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
  }
}

接下来,重点分析 fragmentGet 方法:

private RequestManager fragmentGet(
      @NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
      // 获取一个命名为FRAGMENT_TAG的fragment,如不存在,则新建一个RequestManagerFragment,并添加到当前页面中。
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      Glide glide = Glide.get(context);
      // 创建 RequestManager,RequestManager 会把自己放进生命周期监听器集合里
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
        // 把 RequestManager 设置到当前的 fragment 对象里
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

Glide 是通过在页面中添加一个 Fragment 来动态监听页面的创建和销毁,从而达到依赖页面生命周期,动态管理请求的目的。

那么到底是怎样通过 Fragment 来实现的生命周期监听呢?下面详细分析一下。

首先,看一下 RequestManagerFragment 的构造方法,如下:

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

在构造方法中,构建了一个生命周期监听器对象 ActivityFragmentLifecycle 。然后会在 Fragment 的各个生命周期中调用该监听器的对应的方法。

@Override
public void onAttach(Activity activity) {
  super.onAttach(activity);
  try {
    registerFragmentWithRoot(activity);
  } catch (IllegalStateException e) {
    // OnAttach can be called after the activity is destroyed, see #497.
    if (Log.isLoggable(TAG, Log.WARN)) {
      Log.w(TAG, "Unable to register fragment with root", e);
    }
  }
}

@Override
public void onDetach() {
  super.onDetach();
  unregisterFragmentWithRoot();
}

@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();
}

那么,重点就在于这个监听器对象了,源码如下:

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

  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }
}

主要是将各个 LifecycleListener 对象添加到集合里面,然后在不同的生命周期来遍历处理对应的生命周期方法。那么这个 LifecycleListener 又有谁呢?其实就包括 RequestManager 对象。我们来看一下 RequestManager 里面添加到监听器集合里的代码。

  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.context = context;

    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));    

    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
        // 把自己添加到监听器里,来监听加载的整个生命周期
      lifecycle.addListener(this);
    }
        // 添加网络监听器
    lifecycle.addListener(connectivityMonitor);

    defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
  }

private final Runnable addSelfToLifecycle =
      new Runnable() {
        @Override
        public void run() {
          lifecycle.addListener(RequestManager.this);
        }
  };

由此可知,RequestManagerConnectivityMonitor 都被添加到了生命周期监听。由于每个 with 方法都会实例化一个 RequestManager 对象 和 ConnectivityMonitor 对象,而且这两个对象添加到了生命周期监听,并被设置到了对应的 Fragment 对象里面,所以每个请求都会跟随 fragment 的生命周期。

最后会返回一个 RequestManager 对象,即 Glidewith 对象最终会得到一个 RequestManager 对象。

如果传入的是 applicationContext ,会调用如下方法来获取 RequestManager 对象 :

private RequestManager getApplicationManager(@NonNull Context context) {
  if (applicationManager == null) {
    synchronized (this) {
      if (applicationManager == null) {
        Glide glide = Glide.get(context.getApplicationContext());
          // 构造一个 ApplicationLifecycle 对象传入
        applicationManager =
            factory.build(
                glide,
                new ApplicationLifecycle(),
                new EmptyRequestManagerTreeNode(),
                context.getApplicationContext());
      }
    }
  }

  return applicationManager;
}

至此,总结一下 Glide 的初始化流程:

  1. 获取 Glide 注解自动生成的一个配置器类。
  2. 检索 Manifest 文件配置的 GlideModule 。
  3. 移除重复的 GlideModule 。
  4. 回调 GlideModule 的 applyOptions 方法来配置自定义的属性。
  5. 调用 build 方法来构建 Glide 实例。
  6. 回调 GlideModule 的 registerComponents 方法来注册组件。
  7. 把 glide 实例赋值给单例对象。
  8. 在 RequestManagerRetriever 的重载 get 方法中建立生命周期监听,并返回一个RequestManager。

在上述的第 5 步,build 方法处理的内容如下:

  1. 新建线程池
  2. 新建图片缓存池和缓存池
  3. 新建内存缓存管理器
  4. 新建默认本地缓存管理器
  5. 新建请求引擎Engine
  6. 新建RequestManger检索器
  7. 在 Glide 的构造方法中初始化模型转换器、解码器、转码器和编码器,并对各种类型在注册表一一进行注册。