Glide 初始化流程

参考文档
https://www.jianshu.com/p/a2de3815b932

  1. 在整体流程中Glide对象的获得是通过 Glide.get(context), 那这个get过程都经历哪些初始化流程,做了哪些事情?
  2. 如下代码,我们往往会更改一些自定义的配置,只是继承了抽象类AppGlideModule,并且添加注解@GlideModule 那这个配置是怎么生效的呢?
@GlideModule
public class EmagGlideModule extends AppGlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        ViewTarget.setTagId(R.id.glide_tag);
        if (SystemCompat.getIns().isAndroidGo()) {
            builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_RGB_565)
                    .disallowHardwareConfig());
        } else {
            builder.setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_ARGB_8888));
        }
        builder.setMemoryCache(GlideParams.get().getMemoryCache());
        builder.setBitmapPool(GlideParams.get().getBitmapPool());
        builder.setDiskCache(GlideParams.get().getDiskCacheFactory());
    }

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        // 替换为OKhttp
        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
    }

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }
}

Glide#get(context)

public static Glide get(@NonNull Context context) {
  if (glide == null) {
    // 注释1,获取通过注解动态生成的的AppGlideModule的实现类 
    GeneratedAppGlideModule annotationGeneratedModule =
        getAnnotationGeneratedGlideModules(context.getApplicationContext());
    synchronized (Glide.class) {
      if (glide == null) {
        // 注释2, 检查并初始化Glide
        checkAndInitializeGlide(context, annotationGeneratedModule);
      }
    }
  }

  return glide;
}

  • 采用DCL单例模式
  • 注释1 , 获取通过注解动态生成的的AppGlideModule的实现类
  • 注释2, 检查并初始化Glide

Glide#initializeGlide()

private static void initializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  // 注释1 初始化Glide, 这里直接创建了 GlideBuilder
  initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

private static void initializeGlide(
    @NonNull Context context,
    @NonNull GlideBuilder builder,
    @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
  Context applicationContext = context.getApplicationContext();
  // 注释2 从Manifest获取定义的GlideModule列表, 但有前提条件  且此种方式已标记过时
  List<com.bumptech.glide.module.GlideModule> m anifestModules = Collections.emptyList(); 
  //这里有个判断就是当注解动态生成是空,或者不为空但 isManifestParsingEnabled == true
  if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
    manifestModules = new ManifestParser(applicationContext).parse();
  }

  // 注释3 从注解动态生成的的AppGlideModule的实现类中去掉Manifest定义的GlideMoldue
  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;
      }
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
      }
      iterator.remove();
    }
  }

  if (Log.isLoggable(TAG, Log.DEBUG)) {
    for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
      Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
    }
  }

  // 注释4 实际上我们自定义的AppGlideModule中的Glide的配置,就是通过builder设置的
  // 从44行到57行 就是关联配置
  RequestManagerRetriever.RequestManagerFactory factory =
      annotationGeneratedModule != null
          ? annotationGeneratedModule.getRequestManagerFactory()
          : null;
  //注释5 设置RequestManager的工厂类
  builder.setRequestManagerFactory(factory);
  //注释6 将Manifest定义的GlideModule中的配置选项设置到glideBuilder中
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    module.applyOptions(applicationContext, builder);
  }
  //注释7 将注解动态生成的的AppGlideModule的实现类中的配置选项设置到glideBuilder中
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.applyOptions(applicationContext, builder);
  }
  // 注释8 【Builder设计模式】 创建完毕Glide
  Glide glide = builder.build(applicationContext);

  // 注释9 将Manifest定义的GlideModule中定义的Glide组件注册到Glide中
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    try {
      module.registerComponents(applicationContext, glide, 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);
    }
  }
  // 注释10 将注解动态生成的的AppGlideModule的实现类中定义的Glide组件注册到Glide中
  if (annotationGeneratedModule != null) {
    annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
  }
  // 注释11  让glide监听Application的组件生命周期
  applicationContext.registerComponentCallbacks(glide);
  Glide.glide = glide;
}

通过代码分析,主要初始化流程如下:

  • 注释1 准备初始化Glide, 这里直接创建了 GlideBuilder
  • 注释2 从Manifest获取定义的GlideModule列表, 但有前提条件 且此种方式已标记过时
  • 注释3 从注解动态生成的的AppGlideModule的实现类中去掉Manifest定义的GlideMoldue
  • 注释4 实际上我们自定义的AppGlideModule中的Glide的配置,就是通过builder设置的,从44行到57行 实际就是关联配置
  • 注释5 设置RequestManager的工厂类
  • 注释6 将Manifest定义的GlideModule中的配置选项设置到glideBuilder中
  • 注释7 将注解动态生成的的AppGlideModule的实现类中的配置选项设置到glideBuilder中
  • 注释8 【Builder设计模式】 创建完毕Glide
  • 注释9 将Manifest定义的GlideModule中定义的Glide组件注册到Glide中
  • 注释10 将注解动态生成的的AppGlideModule的实现类中定义的Glide组件注册到Glide中
  • 注释11 让glide监听Application的组件生命周期

这里可以回答开头问题之一,自定义的配置是生效时机

  • 注释7 会调用 我们自定义的EmagGlideModule#applyOptions()
  • 注释10 会调用 我们自定义的EmagGlideModule#registerComponents()

GildeBuilder#build()

对于构建者模式来创建对象已经很熟悉了,我们这里主要是看下GildeBuilder都有哪些配置项

Glide build(@NonNull Context context) {
  // 下面都是创建默认对象:网络加载线程池,磁盘加载线程池,动画加载线程池
  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();
  }

  // 创建bitmap复用池
  if (bitmapPool == null) {
    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) {
    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);
  }

  GlideExperiments experiments = glideExperimentsBuilder.build();
  //创建请求管理器获取器 RequestManagerRetriever
  RequestManagerRetriever requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory, experiments);
  // 将上面的配置参数,构造函数传递给glide进而创建对象,这是一次标准的builder设计模式
  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptionsFactory,
      defaultTransitionOptions,
      defaultRequestListeners,
      experiments);
}

可见,如果外面没有指定的配置,那么都会创建默认的配置项,然后再创建Glide对象,接着我们看下Glide的构造函数又做了哪些事情

Glide#new 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,
    GlideExperiments experiments) {

  /* 正常属性赋值 */
  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();

  /* 注释1 创建注册表,Registry 管理组件注册以扩展或替换 Glide 的默认加载、解码和编码逻辑 */
  registry = new Registry();
  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());
  }

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

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

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
      && experiments.isEnabled(EnableImageDecoderForAnimatedWebp.class)) {
    registry.append(
        Registry.BUCKET_ANIMATION,
        InputStream.class,
        Drawable.class,
        AnimatedWebpDecoder.streamDecoder(imageHeaderParsers, arrayPool));
    registry.append(
        Registry.BUCKET_ANIMATION,
        ByteBuffer.class,
        Drawable.class,
        AnimatedWebpDecoder.byteBufferDecoder(imageHeaderParsers, 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))
      /* Bitmaps */
      .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
      .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder);

  if (ParcelFileDescriptorRewinder.isSupported()) {
    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 */ 
       /* 注册各种转换成gif的图片解码器 */
      .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());
  }

  registry
      .append(int.class, InputStream.class, resourceLoaderStreamFactory)
      .append(int.class, ParcelFileDescriptor.class, resourceLoaderFileDescriptorFactory)
      .append(Integer.class, InputStream.class, resourceLoaderStreamFactory)
      .append(Integer.class, ParcelFileDescriptor.class, resourceLoaderFileDescriptorFactory)
      .append(Integer.class, Uri.class, resourceLoaderUriFactory)
      .append(int.class, AssetFileDescriptor.class, resourceLoaderAssetFileDescriptorFactory)
      .append(Integer.class, AssetFileDescriptor.class, resourceLoaderAssetFileDescriptorFactory)
      .append(int.class, Uri.class, resourceLoaderUriFactory)
      .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))
      .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 */
      /* 注册将Bitmap转换成BitmapDrawable的转换器 */
      .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));
  }

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

整个构造方法主要做了三件事

  1. 属性赋值,GlideBuilder传递过来的值赋值给glide的属性
  2. 注册表注册Registry中包含各种注册表,通过append()或者register()主要包括7种注册表
  3. 创建 GlideContext

Registry#append()Registry#register()

这些注册表封装在这两个方法供调用,这里主要简单熟悉下都有哪些注册表

public class Registry {
...
private final ModelLoaderRegistry modelLoaderRegistry;
private final EncoderRegistry encoderRegistry;
private final ResourceDecoderRegistry decoderRegistry;
private final ResourceEncoderRegistry resourceEncoderRegistry;
private final DataRewinderRegistry dataRewinderRegistry;
private final TranscoderRegistry transcoderRegistry;
private final ImageHeaderParserRegistry imageHeaderParserRegistry;
...

}

  • ModelLoaderRegistry 模型加载器注册表, 维护 ModelLoader 的有序放置以及它们处理的模型和数据类型,按从最高优先级到最低优先级的顺序排列。
  • EncoderRegistry 编码器注册表,包含能够编码任意数据类型的编码器的有序列表。
  • ResourceDecoderRegistry 资源解码器注册表,包含 ResourceDecoder 的有序列表,能够将任意数据类型解码为从最高优先级解码器到最低优先级解码器的任意资源类型。
  • ResourceEncoderRegistry 资源编码器注册表,包含能够编码任意资源类型的 ResourceEncoder 的有序列表。
  • DataRewinderRegistry 数据回卷器注册表,存储数据类到 DataRewinder.Factory 的映射,并允许注册新类型和工厂。
  • TranscoderRegistry 转码器注册表,一个类,它允许 ResourceTranscoders 被它们之间转换的类注册和检索。
  • ImageHeaderParserRegistry 图像头解析器注册表,包含能够解析图像标题的 ImageHeaderParsers 的无序列表。

小结

  • 解析注解定义的AppGlideModule或者Manifest定义的GlideModule,将其对应的配置信息设置给GlideBuilder
  • GlideBuilder设置一些默认的配置信息,比如网络线程池、磁盘线程池、动画线程池、内存缓存、磁盘缓存等
  • GlideBuilder构建Glide,在创建Glide时注册了各种用于图片加载、解码、编码的图片加载器、图片解码器、图片编码器等
  • 将AppGlideModule和GlideModule自定义的图片加载、解码器、编码器注册到Glide中
  • 监听Application的生命周期
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容