Glide源码分析(四)异步加载前奏

在分析异步加载逻辑前,先了解一些相关的类,了解了这些类对后面阅读加载过程会更加轻松

Registry

Glide支持加载格式非常多,into方法可以传入String,File,Uri,Integer等等,加载成功后输出的格式也齐全,asBitmap,asFile,asGif。那么Glide是如何灵活适配这些加载配置的,答案都在Registry里面。

Registry相当于一个注册表,Glide默认已经注册了一大批的配置,初始化和注册配置位置在Glide的构建方法里

Glide(...) {
    ...
    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);

    Downsampler downsampler =
        new Downsampler(
            registry.getImageHeaderParsers(), resources.getDisplayMetrics(), bitmapPool, arrayPool);

    ResourceDecoder<ByteBuffer, Bitmap> byteBufferBitmapDecoder;
    ResourceDecoder<InputStream, Bitmap> streamBitmapDecoder;
    ...
}
    

 里面的配置代码比较多,就不展示全了。除了默认的配置,我们还可以自定义配置。例如我们要适配Okhttp,可以继承AppGlideModule,在registerComponents方法添加。其实第一章分析Glide初始化时已经提及过Registry,忘记的同学可以回头看看

public void registerComponents(Context context, Glide glide,Registry registry) {
//注册Okhttp
    registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client));
}

接下来我们详细看看Registry里面注册的是什么

 可以看到Registry下细分了各种类型

ModelLoaderRegistry

上面okhttp的注册就是注册到这个类里面

  public <Model, Data> Registry replace(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    modelLoaderRegistry.replace(modelClass, dataClass, factory);
    return this;
  }
  • modelClass,就是对应into传递进来的值
  • dataClass,okhttp这里传递进来的是inputStream,可以理解为输出的数据类型
  • ModelLoaderFactory,生成modelLoader的工厂,工厂build方法有个MultiModelLoaderFactory的入参,平时加载网络图片传递的model是String,但okhttp注册的是GlideUrl,它们是怎么匹配上的。逻辑在MultiModelLoaderFactory生成了MultiModelLoader做了装换,这里就不详细分析了,有兴趣的可以深入看看

ModelLoader

public interface ModelLoader<Model, Data> {

  class LoadData<Data> {
    public final Key sourceKey;
    public final List<Key> alternateKeys;
    public final DataFetcher<Data> fetcher;

    public LoadData(@NonNull Key sourceKey, @NonNull DataFetcher<Data> fetcher) {
      this(sourceKey, Collections.<Key>emptyList(), fetcher);
    }

    public LoadData(Key sourceKey, List<Key> alternateKeys,DataFetcher<Data> fetcher) {
      this.sourceKey = Preconditions.checkNotNull(sourceKey);
      this.alternateKeys = Preconditions.checkNotNull(alternateKeys);
      this.fetcher = Preconditions.checkNotNull(fetcher);
    }
  }


  @Nullable
  LoadData<Data> buildLoadData(Model model, int width, int height, Options options);


  boolean handles(@NonNull Model model);
}
  • ModelLoader的主要作用是为了创建内部类LoadData,而handles方法是判断是否适配加载的model,如果匹配才会走下一步buildLoadData创建loadData
  • loadData包含key和DataFetcher,一般key都是ObjectKey,只是简单的包装一下model。而DataFetcher是真正实现加载的类,将modelClass执行加载,输出dataClass

DataFetcher

public interface DataFetcher<T> {

  interface DataCallback<T> {

    void onDataReady(@Nullable T data);

   
    void onLoadFailed(@NonNull Exception e);
  }

  
  void loadData(@NonNull Priority priority, @NonNull DataCallback<? super T> callback);

  
  void cleanup();

  
  void cancel();

  
  Class<T> getDataClass();

  @NonNull
  DataSource getDataSource();
}
  • 定义了CallBack,分别是加载成功和失败,泛型T就是DataClass,所以okhttp返回的是InputStream
  • loadData实现加载的方法,priority是RequestBuilder设置的
  • cleanup是做释放操作的,例如关闭InputSteam
  • DataSource枚举定义图片的来源,可以是网络,本地资源,磁盘缓存

其他注册表

  • ResourceDecoderRegistry - 将DataClass解码,例如InputStream流读取,生成Bitmap。输出的类就是RequestBuilder设置的resourceClass
  • TranscoderRegistry - 转换成as方法设置的资源类型,对应的就是RequestBuilder设置的resourceClass转换成transcodeClass,这两个class类RequestBuilder都支持个性化配置
  • EncoderRegistry - 将图片数据写入到File文件
  • ResourceEncoderRegistry - 图片写入File的策略,用于DiskCacheStrategy磁盘缓存策划判断是否支持

LoadPath

public class LoadPath<Data, ResourceType, Transcode>

抽象定义出注册表多种配置组合出多种加载路线。这个路线是指DataFetcher加载输出DataClass后的路线,三个泛型分别对应分别对应上面的注册表分析,ResourceDecoderRegistry 对应DataClass转换成ResourceType过程,TranscoderRegistry对应ResourceType转换成ResourceType过程。

DiskCacheStrategy

public abstract class DiskCacheStrategy {

  public abstract boolean isDataCacheable(DataSource dataSource);

  
  public abstract boolean isResourceCacheable(
      boolean isFromAlternateCacheKey, DataSource dataSource, EncodeStrategy encodeStrategy);

  
  public abstract boolean decodeCachedResource();

  public abstract boolean decodeCachedData();

}

定义磁盘缓存策略。

  • DataCache指原始未变换过的资源缓存,ResourceCache则是已变换过的资源缓存。
  • 四个方法都是返回boolean,isCacheable作用是判断是否可以缓存内存图片到磁盘,decodeCached则是判断是否可以读取磁盘文件到内存

  • 49
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值