Glide解析(一)—初始化阶段

1,339 阅读13分钟

背景

Glide 作为图片加载框架,开篇不去深究内部实现细节。我们抓住主线,总体来看可以分为以下3个阶段:

  1. 初始化阶段 想要Glide干活,必须就要创建这个干活的对象,如Glide单例对象,当然肯定不只这一个对象。
  2. 请求构造和执行阶段 根据传入的参数如 url 等,构造出 request 对象 ,根据request参数,构造 task,子线程发起请求。
  3. 结果处理阶段 从远端下载得到结果后,需要对输入流 inputStream 进行处理

本篇分析 Glide 的初始化阶段。

一、Glide的初始化

Glide最基本的用法如下:

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

通过一个链式调用完成了加载请求,理所当然先看下with()方法。

1.1 Glide.with()

Glide.java

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

  @NonNull
  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }
  
  @NonNull
  @Deprecated
  public static RequestManager with(@NonNull Activity activity) {
    return with(activity.getApplicationContext());
  }
  
  @Deprecated
  @NonNull
  public static RequestManager with(@NonNull android.app.Fragment fragment) {
    return with(fragment.getContext().getApplicationContext());
  }
  
  public static RequestManager with(@NonNull Fragment fragment) {
    return getRetriever(fragment.getContext()).get(fragment);
  }
 
  @NonNull
  public static RequestManager with(@NonNull View view) {
    return getRetriever(view.getContext()).get(view);
  }

可以看到Glide提供了很多的重载with()方法。内部都调用getRetriever(context)方法,传参为context,因此,生命周期的绑定肯定在getRetriever(context)方法中。

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

由于传入的 fragment.getContext() 在fragment attached前或destroyed后,都会为空,因此这里会做一个判空。getRetriever() 内部调用了Glide的get()静态方法。

1.2 Glide.get() 方法

// 获取glide单例对象:  从静态方法 到 单例对象阶段
  public static Glide get(@NonNull Context context) {
  // 这种写法有点意思,glide对象不在这里赋值,而是在调用的函数里面
    if (glide == null) {
   // annotationGeneratedModule 是注解处理器 根据注解@GlideModule标注的类生成的
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
          
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }

    return glide;
  }
  
  /// 反射获取 GeneratedAppGlideModuleImpl 类,这个类是编译期间通过注解处理器生成的 
    @Nullable
  @SuppressWarnings({"unchecked", "TryWithIdenticalCatches", "PMD.UnusedFormalParameter"})
  private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules(Context context) {
  
    GeneratedAppGlideModule result = null;
    try {
    //com.bumptech.glide.GeneratedAppGlideModuleImpl 反射的路径 
      Class<GeneratedAppGlideModule> clazz =
          (Class<GeneratedAppGlideModule>)
              Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
      result =
          clazz.getDeclaredConstructor(Context.class).newInstance(context.getApplicationContext());
    } catch (ClassNotFoundException e) {
    // 如果没有找到则会打印出warning 错误的提示!
      if (Log.isLoggable(TAG, Log.WARN)) {
        Log.w(
            TAG,
            "Failed to find GeneratedAppGlideModule. You should include an"
                + " annotationProcessor compile dependency on com.github.bumptech.glide:compiler"
                + " in your application and a @GlideModule annotated AppGlideModule implementation"
                + " or LibraryGlideModules will be silently ignored");
      }
      // These exceptions can't be squashed across all versions of Android.
    } catch (InstantiationException e) {
      throwIncorrectGlideModule(e);
    } 
    // 当然你也可以不配置,这里就会返回null
    return result;
  }
  
  /// 重复初始化过滤
    @GuardedBy("Glide.class")
  @VisibleForTesting
  static void checkAndInitializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
    // In the thread running initGlide(), one or more classes may call Glide.get(context).
    // Without this check, those calls could trigger infinite recursion.
    if (isInitializing) {
      throw new IllegalStateException(
          "Glide has been called recursively, this is probably an internal library error!");
    }
    isInitializing = true;
    try {
      initializeGlide(context, generatedAppGlideModule);
    } finally {
      isInitializing = false;
    }
  }
  
  

glide的get()方法会通过反射生成 GeneratedAppGlideModuleImpl 对象。而这个对象是注解处理器在编译期间生成的。注解处理器又是根据在app module中 通过 @GlideModule 注解标记的类(如 GiphyGlideModule)和Manifest.xml中meta_data配置的GlideModule(后者已经被废弃),自动生成的。

最终,GeneratedAppGlideModuleImpl 对象的成员变量 appGlideModule就是GiphyGlideModule 对象的引用,相当于代理模式。

注意: 当然你也可以不配置 AppGlideModule类。如果不配,那么initializeGlide()的第二个参数就是null。

当需要对glide全局配置一些参数时候,就可以配置注解@GlideModule类。

可以往下看静态方法 initializeGlide( context, @Nullable GeneratedAppGlideModule generatedAppGlideModule):

1.2.1 initializeGlide()方法

Glide.java

继续看看 initializeGlide():

  @GuardedBy("Glide.class")
  private static void initializeGlide(
      @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
      ///new GlideBuilder() 这个创建了一个 GlideBuilder 对象
    initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
  }


 @GuardedBy("Glide.class")
  @SuppressWarnings("deprecation")
  private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
      
    Context applicationContext = context.getApplicationContext();
    /// 构造空集合 存储各个module中的清单文件配置的GlideAppModule节点??
    List<GlideModule> manifestModules = Collections.emptyList();
    // 会判断 isManifestParsingEnabled() 这个方法的返回值,如果是false,则不去解析manifest了
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();
    }

    //// 这段代码可以不用管了------>>>>> start 
    if (annotationGeneratedModule != null
        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
      Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
      Iterator<GlideModule> iterator = manifestModules.iterator();
      while (iterator.hasNext()) {
        GlideModule current = iterator.next();
        if (!excludedModuleClasses.contains(current.getClass())) {
          continue;
        }
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
        }
        iterator.remove();
      }
    }
    /// ----<<<<<<<<< end

    if (Log.isLoggable(TAG, Log.DEBUG)) {
      for (GlideModule glideModule : manifestModules) {
        // 这里会打印出所有module配置的 glideModule,不过目前glide建议值在app模块配置
        Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
      }
    }

/   // 构造一个factory来用生成 RequestManager 对象 
    // GeneratedAppGlideModuleImpl 注解生成的类,会重写getRequestManagerFactory()方法。返回一个new GeneratedRequestManagerFactory 对象。 如果Impl不为null则返回这个fatory,否则为null。
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
            
     // 设置 RequestManagerFactory,此时为GeneratedRequestManagerFactory对象
    builder.setRequestManagerFactory(factory);
    
    // 各个module的配置
    for (GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    /// 应用全局的Impl配置 ,我们可以在application中的glideModule中重写这个applyOptions方法,优先级最高
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    // 所有参数都已设置,调用build方法开始构造glide对象
    Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
    
    // 注册监听应用的一些时机回调,如低内存回调、手机配置变化回调。 ComponentCallbacks 
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }


    /// 监听配置变化、低内存时候的回调 
    public interface ComponentCallbacks {
        void onConfigurationChanged(@NonNull Configuration var1);
    
        void onLowMemory();
    }

调用 build() 方法开始构造glide对象。

1.2.2 GlideBuilder 的 build()方法

GlideBuilder.java

@NonNull
  Glide build(
      @NonNull Context context,
      List<GlideModule> manifestModules,
      AppGlideModule annotationGeneratedGlideModule) {
      
    if (sourceExecutor == null) {
    /// 线程执行器,是一个线程池
      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();
    }
    // bitmapPool : LruBitmapPool 或者 BitmapPoolAdapter
    
    if (bitmapPool == null) {
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }
    /// arrayPool ?? 干啥的、、、
    if (arrayPool == null) {
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }
    /// 资源res缓存
    if (memoryCache == null) {
    // 如果外部没有设置,则使用默认的
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }
    // 创建engine
    if (engine == null) {
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

    //确保 defaultRequestListeners不为null
    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }
    

    GlideExperiments experiments = glideExperimentsBuilder.build();
    /// requestManager获取器,传入了一个requestManagerFactory

    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);
    /// 创建glide对象
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        manifestModules,
        annotationGeneratedGlideModule,
        experiments);
  }

职责:

  1. 构造各种功能的工作线程池

    • sourceExecutor

    线程池,核心和最大线程数都是4(如果设备CPU小于4核,则以设备的核数为准),且不会主动销毁。线程名字为 glide-source-thread-threadNum(1/2/3/4)。用途:用来 load/decode/transform 非缓存的数据,也就是源数据。

    • diskCacheExecutor

    核心和最大线程数都是1,且不会主动销毁。线程名字为 glide-disk-cache-thread-1。用途:用来 load/decode/transform 缓存中的数据。

    • animationExecutor

    核心和最大线程数都是2(当手机的CPU核数>=4)或者1(反之),且不会主动销毁。线程名字为 glide-animation-thread-1。用途:用来处理动画逻辑。

  2. 网络监听 这里会涉及到不同系统版本的适配(glide方案):

    • Android7.0-24前使用动态广播 context.registerReceiver()
    • Android 7.0后使用api connectivityManager.registerDefaultNetworkCallback(networkCallback);
  3. 构造缓存相关pools

  4. 构造engine对象

  5. 构造 RequestManagerRetriever 对象,用来生成 RequestManager 对象

  6. 构造glide对象并返回

requestManagerRetriever,传入了一个requestManagerFactory,此时 requestManagerFactory 不为null(也存在为null的情况,会使用默认的fatory)。

1.3 RequestManagerRetriever 的构造方法

RequestManagerRetriever.java

public class RequestManagerRetriever implements Handler.Callback {
  public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
      
    //   factory在没有配置注解的情况加就使用默认工厂
    this.factory = factory != null ? factory : DEFAULT_FACTORY;
    
    handler = new Handler(Looper.getMainLooper(), this /* Callback */);
    
    lifecycleRequestManagerRetriever = new LifecycleRequestManagerRetriever(this.factory);
    frameWaiter = buildFrameWaiter();
  }

 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) {
            // 构造一个 RequestManager 对象
          return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
        }
      };
    // ... 
}
  1. factory 不为null,则会创建 GlideRequests 对象, GlideRequests继承了 RequestManager。
  2. factory为null,则直接创建 RequestManager 对象

总结: GlideRequests 是自动生成的,最终的逻辑都是在 RequestManager中

1.4 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,
      @NonNull List<GlideModule> manifestModules,
      @Nullable AppGlideModule annotationGeneratedModule,
      @NonNull GlideExperiments experiments) {
    this.engine = engine;
    this.bitmapPool = bitmapPool;
    this.arrayPool = arrayPool;
    this.memoryCache = memoryCache;
    this.requestManagerRetriever = requestManagerRetriever;
    this.connectivityMonitorFactory = connectivityMonitorFactory;
    this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;

    // This has a circular relationship with Glide and GlideContext in that it depends on both,
    // but it's created by Glide's constructor. In practice this shouldn't matter because the
    // supplier holding the registry should never be initialized before this constructor finishes.
    
    // Glide支持器 很重要,会注册需要的各种处理器,比如modelLoader、decoder等,后面发起网络请求的时候会用到
    GlideSupplier<Registry> registry =
        RegistryFactory.lazilyCreateAndInitializeRegistry(
            this, manifestModules, annotationGeneratedModule);

    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    
    // 创建 glideContext 对象
    glideContext =
        new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptionsFactory,
            defaultTransitionOptions,
            defaultRequestListeners,
            engine,
            experiments,
            logLevel);
  }

构造方法中的 RegistryFactory.lazilyCreateAndInitializeRegistry() 很重要,这里涉及到后续的请求发起逻辑。

1.4.1 RegistryFactory.lazilyCreateAndInitializeRegistry()

RegistryFactory.java

static GlideSupplier<Registry> lazilyCreateAndInitializeRegistry(
      final Glide glide,
      final List<GlideModule> manifestModules,
      @Nullable final AppGlideModule annotationGeneratedModule) {
      
      // 返回支持器对象 
    return new GlideSupplier<Registry>() {
      // Rely on callers using memoization if they want to avoid duplicate work, but
      // rely on ourselves to verify that no recursive initialization occurs.
      private boolean isInitializing;

      @Override
      public Registry get() {
        if (isInitializing) {
          throw new IllegalStateException(
              "Recursive Registry initialization! In your"
                  + " AppGlideModule and LibraryGlideModules, Make sure you're using the provided "
                  + "Registry rather calling glide.getRegistry()!");
        }
        Trace.beginSection("Glide registry");
        isInitializing = true;
        try {
          return createAndInitRegistry(glide, manifestModules, annotationGeneratedModule);
        } finally {
          isInitializing = false;
          Trace.endSection();
        }
      }
    };
  }
  
  // 创建和初始化注册器
    @Synthetic
  static Registry createAndInitRegistry(
      Glide glide,
      List<GlideModule> manifestModules,
      @Nullable AppGlideModule annotationGeneratedModule) {

    // bitmapPool和 ArrayPool
    BitmapPool bitmapPool = glide.getBitmapPool();
    ArrayPool arrayPool = glide.getArrayPool();
    
    Context context = glide.getGlideContext().getApplicationContext();

    GlideExperiments experiments = glide.getGlideContext().getExperiments();
    // 构建一个 Register 对象  很重要
    Registry registry = new Registry();
    // 初始化各种编码器、解码器,fetch等   很重要
    initializeDefaults(context, registry, bitmapPool, arrayPool, experiments);
    // 提供给业务方自定义的功能,如使用okhttp来获取网络图片,而不是默认的HttpUrlConnection
    initializeModules(context, glide, registry, manifestModules, annotationGeneratedModule);
    return registry;
  }

1.4.2 RegistryFactory.initializeDefaults() 方法

 private static void initializeDefaults(
      Context context,
      Registry registry,
      BitmapPool bitmapPool,
      ArrayPool arrayPool,
      GlideExperiments experiments) {
      
    registry.register(new DefaultImageHeaderParser());
    
    // Right now we're only using this parser for HEIF images, which are only supported on OMR1+.
    // If we need this for other file types, we should consider removing this restriction.
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
      registry.register(new ExifInterfaceImageHeaderParser());
    }

    final Resources resources = context.getResources();
    List<ImageHeaderParser> imageHeaderParsers = registry.getImageHeaderParsers();

    // decoder
    ByteBufferGifDecoder byteBufferGifDecoder =
        new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);
    ResourceDecoder<ParcelFileDescriptor, Bitmap> parcelFileDescriptorVideoDecoder =
        VideoDecoder.parcel(bitmapPool);

    // TODO(judds): Make ParcelFileDescriptorBitmapDecoder work with ImageDecoder.
    Downsampler downsampler =
        new Downsampler(
            registry.getImageHeaderParsers(), resources.getDisplayMetrics(), bitmapPool, arrayPool);

    ResourceDecoder<ByteBuffer, Bitmap> byteBufferBitmapDecoder;
    ResourceDecoder<InputStream, Bitmap> streamBitmapDecoder;
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
        && experiments.isEnabled(EnableImageDecoderForBitmaps.class)) {
      streamBitmapDecoder = new InputStreamBitmapImageDecoderResourceDecoder();
      byteBufferBitmapDecoder = new ByteBufferBitmapImageDecoderResourceDecoder();
    } else {
      byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
      streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
    }

    // 1. ResourceDecoderRegistry 注册阶段 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { // android9.0 >> 28 
    // 注册动画的 解码器
    // 内部实现:最终存储到 ResourceDecoderRegistry 类中的 Map<String, List<Entry<?, ?>>> decoders = new HashMap<>();
    
    // 通过decoders 集合来存储解码器。以bucket为key,value是一个list,list中元素是Entry对象(也就是append的参数封装成了额Entry对象),根据dataClass和resourceClass来区分选择。
      registry.append( 
          Registry.BUCKET_ANIMATION, // "Animation" ,作为key
          InputStream.class,  //dataClass
          Drawable.class, //  resourceClass
          AnimatedImageDecoder.streamDecoder(imageHeaderParsers, arrayPool) // decoder
          
          ); 
      registry.append(
          Registry.BUCKET_ANIMATION,
          ByteBuffer.class,
          Drawable.class,
          AnimatedImageDecoder.byteBufferDecoder(imageHeaderParsers, arrayPool));
    }

    // 创建 编码器/解码器 对象
    ResourceDrawableDecoder resourceDrawableDecoder = new ResourceDrawableDecoder(context);
    BitmapEncoder bitmapEncoder = new BitmapEncoder(arrayPool);
    BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();
    GifDrawableBytesTranscoder gifDrawableBytesTranscoder = new GifDrawableBytesTranscoder();

    // 
    ContentResolver contentResolver = context.getContentResolver();

    // 2.EncoderRegistry 注册解码器阶段 
    // 这个重载的append()方法会存储到 EncoderRegistry类 的成员变量encoders中 
    // encodes编码器 注册
    private final List<Entry<?>> encoders = new ArrayList<>();
    registry
        .append(ByteBuffer.class, new ByteBufferEncoder()) // 第一个参数 dataClass, 第二个是 encoder
        .append(InputStream.class, new StreamEncoder(arrayPool))
        
        /* Bitmaps */ 这个重载方法还是会存储到 ResourceDecoderRegistry
        .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
        .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder);

    if (ParcelFileDescriptorRewinder.isSupported()) {
    // 是否支持parcel,跨进程传递
      registry.append(
          Registry.BUCKET_BITMAP,
          ParcelFileDescriptor.class,
          Bitmap.class,
          new ParcelFileDescriptorBitmapDecoder(downsampler));
    }

    registry
        .append(
            Registry.BUCKET_BITMAP,
            ParcelFileDescriptor.class,
            Bitmap.class,
            parcelFileDescriptorVideoDecoder)
        .append(
            Registry.BUCKET_BITMAP,
            AssetFileDescriptor.class,
            Bitmap.class,
            VideoDecoder.asset(bitmapPool))
            
        .append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
        .append(Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())
        .append(Bitmap.class, bitmapEncoder)
        
        /* BitmapDrawables */ BitmapDrawable 开始注册 
        .append(
            Registry.BUCKET_BITMAP_DRAWABLE,
            ByteBuffer.class,
            BitmapDrawable.class,
            new BitmapDrawableDecoder<>(resources, byteBufferBitmapDecoder))
        .append(
            Registry.BUCKET_BITMAP_DRAWABLE,
            InputStream.class,
            BitmapDrawable.class,
            new BitmapDrawableDecoder<>(resources, streamBitmapDecoder))
        .append(
            Registry.BUCKET_BITMAP_DRAWABLE,
            ParcelFileDescriptor.class,
            BitmapDrawable.class,
            new BitmapDrawableDecoder<>(resources, parcelFileDescriptorVideoDecoder))
        .append(BitmapDrawable.class, new BitmapDrawableEncoder(bitmapPool, bitmapEncoder))
        
        
        /* GIFs */
        .append(
            Registry.BUCKET_ANIMATION,
            InputStream.class,
            GifDrawable.class,
            new StreamGifDecoder(imageHeaderParsers, byteBufferGifDecoder, arrayPool))
        .append(
            Registry.BUCKET_ANIMATION, ByteBuffer.class, GifDrawable.class, byteBufferGifDecoder)
        .append(GifDrawable.class, new GifDrawableEncoder())
        
        
        /* GIF Frames */
        // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
        .append(
            GifDecoder.class, GifDecoder.class, UnitModelLoader.Factory.<GifDecoder>getInstance())
        .append(
            Registry.BUCKET_BITMAP,
            GifDecoder.class,
            Bitmap.class,
            new GifFrameResourceDecoder(bitmapPool))
        /* Drawables */
        .append(Uri.class, Drawable.class, resourceDrawableDecoder)
        .append(
            Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitmapPool))
            
            
        /* Files */
        .register(new ByteBufferRewinder.Factory())
        
        .append(File.class, ByteBuffer.class, new ByteBufferFileLoader.Factory())
        .append(File.class, InputStream.class, new FileLoader.StreamFactory())
        .append(File.class, File.class, new FileDecoder())
        .append(File.class, ParcelFileDescriptor.class, new FileLoader.FileDescriptorFactory())
        // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
        .append(File.class, File.class, UnitModelLoader.Factory.<File>getInstance())
        
        /* Models */
        
        .register(new InputStreamRewinder.Factory(arrayPool));

    if (ParcelFileDescriptorRewinder.isSupported()) {
      registry.register(new ParcelFileDescriptorRewinder.Factory());
    }

    // DirectResourceLoader and ResourceUriLoader handle resource IDs and Uris owned by this
    // package.
    
    // 3. ModelLoaderRegistry  注册
    
    ModelLoaderFactory<Integer, InputStream> directResourceLoaderStreamFactory =
        DirectResourceLoader.inputStreamFactory(context);
        
    ModelLoaderFactory<Integer, AssetFileDescriptor>
        directResourceLoaderAssetFileDescriptorFactory =
            DirectResourceLoader.assetFileDescriptorFactory(context);
            
    ModelLoaderFactory<Integer, Drawable> directResourceLaoderDrawableFactory =
        DirectResourceLoader.drawableFactory(context);
        
        // 内部会调用 ModelLoaderRegistry 的 append方法,最终存储到 MultiModelLoaderFactory的 List<Entry<?, ?>> entries = new ArrayList<>();中
    registry
        //第一个参数是 modelClass,  第二个参数是 dataClass 
        .append(int.class, InputStream.class, directResourceLoaderStreamFactory)
        .append(Integer.class, InputStream.class, directResourceLoaderStreamFactory)
        .append(
            int.class, AssetFileDescriptor.class, directResourceLoaderAssetFileDescriptorFactory)
        .append(
            Integer.class,
            AssetFileDescriptor.class,
            directResourceLoaderAssetFileDescriptorFactory)
        .append(int.class, Drawable.class, directResourceLaoderDrawableFactory)
        .append(Integer.class, Drawable.class, directResourceLaoderDrawableFactory)
        .append(Uri.class, InputStream.class, ResourceUriLoader.newStreamFactory(context))
        .append(
            Uri.class,
            AssetFileDescriptor.class,
            ResourceUriLoader.newAssetFileDescriptorFactory(context));

    // ResourceLoader and UriLoader handle resource IDs and Uris owned by other packages.
    ResourceLoader.UriFactory resourceLoaderUriFactory = new ResourceLoader.UriFactory(resources);
    
    ResourceLoader.AssetFileDescriptorFactory resourceLoaderAssetFileDescriptorFactory =
        new ResourceLoader.AssetFileDescriptorFactory(resources);
        
    ResourceLoader.StreamFactory resourceLoaderStreamFactory =
        new ResourceLoader.StreamFactory(resources);
         //第一个参数是 modelClass,  第二个参数是 dataClass 
    registry
        .append(Integer.class, Uri.class, resourceLoaderUriFactory)
        .append(int.class, Uri.class, resourceLoaderUriFactory)
        .append(Integer.class, AssetFileDescriptor.class, resourceLoaderAssetFileDescriptorFactory)
        .append(int.class, AssetFileDescriptor.class, resourceLoaderAssetFileDescriptorFactory)
        .append(Integer.class, InputStream.class, resourceLoaderStreamFactory)
        .append(int.class, InputStream.class, resourceLoaderStreamFactory);

    registry
        .append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())
        .append(Uri.class, InputStream.class, new DataUrlLoader.StreamFactory<Uri>())
        .append(String.class, InputStream.class, new StringLoader.StreamFactory())
        .append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
        .append(
            String.class, AssetFileDescriptor.class, new StringLoader.AssetFileDescriptorFactory())
        .append(Uri.class, InputStream.class, new AssetUriLoader.StreamFactory(context.getAssets()))
        .append(
            Uri.class,
            AssetFileDescriptor.class,
            new AssetUriLoader.FileDescriptorFactory(context.getAssets()))
        .append(Uri.class, InputStream.class, new MediaStoreImageThumbLoader.Factory(context))
        .append(Uri.class, InputStream.class, new MediaStoreVideoThumbLoader.Factory(context));
        
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      registry.append(
          Uri.class, InputStream.class, new QMediaStoreUriLoader.InputStreamFactory(context));
      registry.append(
          Uri.class,
          ParcelFileDescriptor.class,
          new QMediaStoreUriLoader.FileDescriptorFactory(context));
    }
    registry
        .append(Uri.class, InputStream.class, new UriLoader.StreamFactory(contentResolver))
        .append(
            Uri.class,
            ParcelFileDescriptor.class,
            new UriLoader.FileDescriptorFactory(contentResolver))
        .append(
            Uri.class,
            AssetFileDescriptor.class,
            new UriLoader.AssetFileDescriptorFactory(contentResolver))
        .append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())
        .append(URL.class, InputStream.class, new UrlLoader.StreamFactory())
        .append(Uri.class, File.class, new MediaStoreFileLoader.Factory(context))
        // 注册httpGlide modelLoader
        .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
        .append(byte[].class, ByteBuffer.class, new ByteArrayLoader.ByteBufferFactory())
        .append(byte[].class, InputStream.class, new ByteArrayLoader.StreamFactory())
        .append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance())
        .append(Drawable.class, Drawable.class, UnitModelLoader.Factory.<Drawable>getInstance())
        .append(Drawable.class, Drawable.class, new UnitDrawableDecoder())
        /* Transcoders */
        .register(Bitmap.class, BitmapDrawable.class, new BitmapDrawableTranscoder(resources))
        .register(Bitmap.class, byte[].class, bitmapBytesTranscoder)
        .register(
            Drawable.class,
            byte[].class,
            new DrawableBytesTranscoder(
                bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder))
        .register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      ResourceDecoder<ByteBuffer, Bitmap> byteBufferVideoDecoder =
          VideoDecoder.byteBuffer(bitmapPool);
      registry.append(ByteBuffer.class, Bitmap.class, byteBufferVideoDecoder);
      
      registry.append(
          ByteBuffer.class,
          BitmapDrawable.class,
          new BitmapDrawableDecoder<>(resources, byteBufferVideoDecoder));
    }
  }

1.4.3 RegistryFactory.initializeModules()

 private static void initializeModules(
      Context context,
      Glide glide,
      Registry registry,
      List<GlideModule> manifestModules,
      @Nullable AppGlideModule annotationGeneratedModule) {
      
      // 遍历清单文件中的glideModule ,glideV4不建议这样使用了!!
    for (GlideModule module : manifestModules) {
      try {
        module.registerComponents(context, glide, registry);
      } catch (AbstractMethodError e) {
        throw new IllegalStateException(
            "Attempting to register a Glide v3 module. If you see this, you or one of your"
                + " dependencies may be including Glide v3 even though you're using Glide v4."
                + " You'll need to find and remove (or update) the offending dependency."
                + " The v3 module name is: "
                + module.getClass().getName(),
            e);
      }
    }
    if (annotationGeneratedModule != null) {
    // 会回调app自己定义的GlideModule类的 registerComponents方法,
    // 目的就是让业务方自己通过 registry 注册一些自己的factory
      annotationGeneratedModule.registerComponents(context, glide, registry);
    }
  }

会回调app自己定义的 GlideAppModule 类的 registerComponents()方法,让业务方注册一些自定义factory。

比如demo中GiphyGlideModule:

@GlideModule
public class GiphyGlideModule extends AppGlideModule {

  /// 这个方法会被回调
  @Override
  public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
    super.applyOptions(context, builder);
  }

  @Override
  public void registerComponents(
      @NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
    registry.append(Api.GifResult.class, InputStream.class, new GiphyModelLoader.Factory());
  }

  // Disable manifest parsing to avoid adding similar modules twice.
  @Override
  public boolean isManifestParsingEnabled() {
    return false;
  }
}

1.5 小结

我们通过调用glide的 with()方法,getRetriver()方法内部调用glide的get()方法,在这个过程中会创建glide对象,并且完成一系列的初始化工作,最终得到了一个RequestManagerRetriever对象。

但是with()方法需要返回的是 RequestManager 对象。因此我们要回到 with()方法中,继续看看 RequestManagerRetriever的 get()方法。

1.6 RequestManagerRetriever.get()方法

RequestManagerRetriever.java

跟glide的with()方法类似,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) {
      // 主线程,则把上下文context 强转成FragmentActivity
        return get((FragmentActivity) context);
      } else if (context instanceof ContextWrapper
          // Only unwrap a ContextWrapper if the baseContext has a non-null application context.
          // Context#createPackageContext may return a Context without an Application instance,
          // in which case a ContextWrapper may be used to attach one.
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
          // 如果是wrapper,则获取mBase 
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
    //如果是后台线程,则创建一个applicationManager对象,用来干啥??
    return getApplicationManager(context);
  }

  @NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
  // 如果是后台线程
    if (Util.isOnBackgroundThread()) {
    // 创建后台线程对应applicationManager 
      return get(activity.getApplicationContext());
    }
    // 如果activity.isDestroyed(),那么抛出异常
    assertNotDestroyed(activity);
    frameWaiter.registerSelf(activity);
    // activity是否在可见栈中
    boolean isActivityVisible = isActivityVisible(activity);
    // 获取glide对象实例
    Glide glide = Glide.get(activity.getApplicationContext());
    
    // 主线程:获取或者创建一个 RequestManager对象
    return lifecycleRequestManagerRetriever.getOrCreate(
        activity,
        glide,
        activity.getLifecycle(), // 监听FragmentActivity的生命周期回调
        activity.getSupportFragmentManager(), //fm
        isActivityVisible);
  }

  @NonNull
  public RequestManager get(@NonNull Fragment fragment) {
    Preconditions.checkNotNull(
        fragment.getContext(),
        "You cannot start a load on a fragment before it is attached or after it is destroyed");
    if (Util.isOnBackgroundThread()) {
      return get(fragment.getContext().getApplicationContext());
    }
    // In some unusual cases, it's possible to have a Fragment not hosted by an activity. There's
    // not all that much we can do here. Most apps will be started with a standard activity. If
    // we manage not to register the first frame waiter for a while, the consequences are not
    // catastrophic, we'll just use some extra memory.
    if (fragment.getActivity() != null) {
      frameWaiter.registerSelf(fragment.getActivity());
    }
    FragmentManager fm = fragment.getChildFragmentManager();
    Context context = fragment.getContext();
    Glide glide = Glide.get(context.getApplicationContext());
    
    return lifecycleRequestManagerRetriever.getOrCreate(
        context, glide, fragment.getLifecycle(), fm, fragment.isVisible());
  }

  /**
   * @deprecated This is identical to calling {@link #get(Context)} with the application context.
   *     Use androidx Activities instead (ie {@link FragmentActivity}, or {@link
   *     androidx.appcompat.app.AppCompatActivity}).
   */
  @Deprecated
  @NonNull
  public RequestManager get(@NonNull Activity activity) {
    return get(activity.getApplicationContext());
  }

  @NonNull
  public RequestManager get(@NonNull 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.
    // 找 support fragment的过程,花销比较大 
    if (activity instanceof FragmentActivity) {
      Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
      return fragment != null ? get(fragment) : get((FragmentActivity) activity);
    }

    // Standard Fragments.
    return get(view.getContext().getApplicationContext());
  }


1.6.1 getApplicationManager()方法

RequestManagerRetriever.java

 @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 就是之前提到的 RequestManagerFactory,用来构造 RequestManager 对象。

以上代码的职责:

  1. 如果在子线程,则创建一个applicationRequestManager,生命周期跟app一样
  2. 如果在主线程,则通过 lifecycleRequestManagerRetriever.getOrCreate() 方法,来获取 RequestManager 对象 ,生命周期跟 acitivity 绑定

我们继续看看 lifecycleRequestManagerRetriever 的getOrCreate()方法:

1.6.2 lifecycleRequestManagerRetriever.getOrCreate() 方法

// 返回一个 RequestManager 对象 
RequestManager getOrCreate(
      Context context,
      Glide glide,
      final Lifecycle lifecycle,
      FragmentManager childFragmentManager,
      boolean isParentVisible) {
      // 判断是否在主线程
    Util.assertMainThread();
    
    // 以lifecycle为key,l从map中获取 requestManager
    // 每一个activity的生命周期 对应一个请求管理者 requestManager
    RequestManager result = getOnly(lifecycle);
    if (result == null) {
    // 监听当前页面的生命周期
      LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
      // new 一个 requestManager 对象
      result =
          factory.build(
              glide,
              glideLifecycle,
              new SupportRequestManagerTreeNode(childFragmentManager),
              context);
      lifecycleToRequestManager.put(lifecycle, result);
      glideLifecycle.addListener(
          new LifecycleListener() {
            @Override
            public void onStart() {}

            @Override
            public void onStop() {}

            @Override
            public void onDestroy() {
              lifecycleToRequestManager.remove(lifecycle);
            }
          });
      // This is a bit of hack, we're going to start the RequestManager, but not the
      // corresponding Lifecycle. It's safe to start the RequestManager, but starting the
      // Lifecycle might trigger memory leaks. See b/154405040
      if (isParentVisible) {
        result.onStart();
      }
    }
    return result;
  }

到这里,我们得到了每一个页面对应的 RequestManager 对象。这个 RequestManager 对象是跟当前页面的生命周期绑定的。

1.6.3 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));

    // Order matters, this might be unregistered by teh listeners below, so we need to be sure to
    // register first to prevent both assertions and memory leaks.
    glide.registerRequestManager(this);

    // If we're the application level request manager, we may be created on a background thread.
    // In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
    // issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
    // This should be entirely safe.
    // 需要在主线程监听
    if (Util.isOnBackgroundThread()) {
      Util.postOnUiThread(addSelfToLifecycle);
    } else {
    // 注册监听
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

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

RequestManager 构造方法会注册当前页面的生命周期监听,目的是同步给view,从而在页面可见和不可见的时候,控制显示逻辑。

疑问:RequestManager如何感知activity/fragment的生命周期呢?

这就涉及到了两个类,Support Library 26.1.0 及其以后的版本/androidx的appcompat包,Activity 和Fragment 已经实现了 LifecycleOwner 接口,所以,我们可以直接在Activity 和Fragment中使用getLifecycle()方法来获取lifecycle对象,来添加观察者监听即可。

1.7 有关生命周期绑定的改动

  • 在2022.8.3之前是通过添加空白fragment来感知页面生命周期的
  • 之后则是废弃了support包的fragment/activity,从而支持androidx包的fragment 生命周期LifecycleOwner 新接口

1.8 小结

至此,我们需要学习了glide的with()方法,它返回一个 RequestManager对象,内部完成了glide的初始化逻辑。后续将继续学习glide的请求构造和执行阶段。

二、参考

blog.yorek.xyz/android/3rd…

juejin.cn/post/688253…

juejin.cn/post/713690…