Glide附件难点之上篇源码文章

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/wangwei708846696/article/details/83047100

注册

Glide.Glide()

GenericLoaderFactory的注册

register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
register(File.class, InputStream.class, new StreamFileLoader.Factory());
register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(int.class, InputStream.class, new StreamResourceLoader.Factory());
register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
register(String.class, InputStream.class, new StreamStringLoader.Factory());
register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());
Map<Class/*T*/, Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/>>  modelClassToResourceFactories;

image

小结的图如下:

  • File
    • ParcelFileDescriptor : FileDescriptorFileLoader
    • InputStream : StreamFileLoader
  • int
    • ParcelFileDescriptor : FileDescriptorResourceLoader
    • InputStream : StreamResourceLoader
  • Integer
    • ParcelFileDescriptor : FileDescriptorResourceLoader
    • InputStream : StreamResourceLoader
  • String
    • ParcelFileDescriptor:FileDescriptorStringLoader
    • InputStream:StreamStringLoader
  • Uri
    • ParcelFileDescriptor:FileDescriptorUriLoader
    • InputStream:StreamUriLoader
  • URL
    • InputStream:StreamUrlLoader
  • GlideUrl
    • InputStream:HttpUrlGlideUrlLoader
  • byte
    • InputStream:StreamByteArrayLoader

DataLoadProviderRegistry的注册:

StreamBitmapDataLoadProvider streamBitmapLoadProvider =
        new StreamBitmapDataLoadProvider(bitmapPool, decodeFormat);
dataLoadProviderRegistry.register(InputStream.class, Bitmap.class, streamBitmapLoadProvider);

FileDescriptorBitmapDataLoadProvider fileDescriptorLoadProvider =
        new FileDescriptorBitmapDataLoadProvider(bitmapPool, decodeFormat);
dataLoadProviderRegistry.register(ParcelFileDescriptor.class, Bitmap.class, fileDescriptorLoadProvider);

ImageVideoDataLoadProvider imageVideoDataLoadProvider =
        new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);
dataLoadProviderRegistry.register(ImageVideoWrapper.class, Bitmap.class, imageVideoDataLoadProvider);

GifDrawableLoadProvider gifDrawableLoadProvider =
        new GifDrawableLoadProvider(context, bitmapPool);
dataLoadProviderRegistry.register(InputStream.class, GifDrawable.class, gifDrawableLoadProvider);

dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
        new ImageVideoGifDrawableLoadProvider(imageVideoDataLoadProvider, gifDrawableLoadProvider, bitmapPool));

dataLoadProviderRegistry.register(InputStream.class, File.class, new StreamFileDataLoadProvider());
//new MultiClassKey(dataClass, resourceClass),provider
Map<MultiClassKey, DataLoadProvider<?, ?>> providers;
//注册进了
Map<MultiClassKey, DataLoadProvider<?, ?>> providers;
providers.put(new MultiClassKey(dataClass, resourceClass), provider);

image

  • InputStream
    • Bitmap : StreamBitmapDataLoadProvider
    • GifDrawable : GifDrawableLoadProvider
    • File : StreamFileDataLoadProvider
  • ParcelFileDescriptor
    • Bitmap : FileDescriptorBitmapDataLoadProvider
  • ImageVideoWrapper
    • Bitmap : ImageVideoDataLoadProvider
    • GifBitmapWrapper : ImageVideoGifDrawableLoadProvider

TranscoderRegistry 的注册

Map<MultiClassKey, ResourceTranscoder<?, ?>> factories;

image

  • Bitmap + GlideBitmapDrawable
    • GlideBitmapDrawableTranscoder
  • GifBitmapWrapper + GlideDrawable
    • GifBitmapWrapperDrawableTranscoder( GlideBitmapDrawableTranscoder )

获取

//modelClass是String.class,resourceClass是InputStream.class
Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);

同样在注册工厂列表中找

//例子中的根据String.class和InputStream.class找到ModelLoaderFactory,所以得到StreamStringLoader
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);

所以buildModelLoader是获取工厂列表数据

ModelLoader是通过对应工厂得到的不同解析不同数据类型的模型

注册表操作关系图

image

DrawableTypeRequest类

继承关系

GenericRequestBuilder
    DrawableRequestBuilder
        DrawableTypeRequest

参数关系

DrawableTypeRequest:

  • 该类拥有ModelLoader<ModelType, InputStream> streamModelLoader 注册的工厂对象所生成的产物
  • 该类拥有ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader 同理上面
  • 该类拥有RequestManager.OptionsApplier optionsApplier RequestManager构造中的OptionsApplier对象
  • Class<ModelType> modelClass 用户最初传进来的类型,在注册表中用作key,本例是String.class
  • Context context 上下文
  • Glide glide 核心类
  • RequestTracker requestTracker RequestManager构造中的RequestTracker对象
  • Lifecycle lifecycle 生命周期与Activity绑定

DrawableRequestBuilder:
无本类所特有

  • Context context 上下文
  • Class<ModelType> modelClass
  • FixedLoadProvider loadProvider
  • Glide glide
  • RequestTracker requestTracker
  • Lifecycle lifecycle

GenericRequestBuilder:

  • Context context 上下文
  • Class<ModelType> modelClass
  • FixedLoadProvider loadProvider 包装成ChildLoadProvider
  • 本类特有Class<TranscodeType> transcodeClass 是GlideDrawable.class
  • Glide glide
  • RequestTracker requestTracker
  • Lifecycle lifecycle

核心的是DrawableTypeRequest构造了一个FixedLoadProvider对象传递给父DrawableRequestBuilder

FixedLoadProvider的构造过程

代码如下:

private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(
        Glide glide,
        ModelLoader<A, InputStream> streamModelLoader,
        ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, 
        Class<Z> resourceClass,
        Class<R> transcodedClass,
        ResourceTranscoder<Z, R> transcoder) {
        
    if (streamModelLoader == null && fileDescriptorModelLoader == null) {
        return null;
    }

    if (transcoder == null) {
        //根据GifBitmapWrapper.class和GlideDrawable.class生成ResourceTranscoder
        //这个过程也是在Glide构造过程中的到GifBitmapWrapperDrawableTranscoder( GlideBitmapDrawableTranscoder )
        transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
    }
    //根据ImageVideoWrapper.class和GifBitmapWrapper.class得到ImageVideoGifDrawableLoadProvider,根据provider的注册表
    DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class, resourceClass);
    //根据StreamStringLoader和FileDescriptorStringLoader生成ImageVideoModelLoader
    ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader, fileDescriptorModelLoader);
    return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
}

传入进行制造的参数:

  • Glide glide
  • ModelLoader<A, InputStream> streamModelLoader
  • ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader
  • Class<Z> resourceClass 实际对象是GifBitmapWrapper.class
  • Class<R> transcodedClass 实际对象是GlideDrawable.class
  • ResourceTranscoder<Z, R> transcoder null

FixedLoadProvider需要的参数

  • ModelLoader<A, T> modelLoader ImageVideoModelLoader(StreamStringLoader , FileDescriptorStringLoader)
  • ResourceTranscoder<Z, R> transcoder GifBitmapWrapperDrawableTranscoder(GlideBitmapDrawableTranscoder)
  • DataLoadProvider<T, Z> dataLoadProvider ImageVideoGifDrawableLoadProvider

DrawableRequestBuilder.into()

into方法之前用load将所需url传入

public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
    this.model = model;//记录的是String类型的url,在此场景中
    isModelSet = true;
    return this;
}
@Override
public Target<GlideDrawable> into(ImageView view) {
    return super.into(view);
}

//GenericRequestBuilder
public Target<TranscodeType> into(ImageView view) {
    ...
    //transcodeClass在此情景中是GlideDrawable.class
    return into(glide.buildImageViewTarget(view, transcodeClass));
}

其中用glide的buildImageViewTarget方法利用ImageViewTargetFactory的buildTarget将生成一个Target的子类
在此场景中对应GlideDrawableImageViewTarget

此时进入到into方法的核心,所以看出来GenericRequestBuilder这个类就可以创建出一个Request

GenericRequestBuilder.into()

public <Y extends Target<TranscodeType>> Y into(Y target) {
    ...
    Request request = buildRequest(target);//根据传入的GlideDrawableImageViewTarget进行构造一个Request
    target.setRequest(request);
    lifecycle.addListener(target);
    requestTracker.runRequest(request);//执行请求
    return target;
}

神奇的是RequestTracker竟然是执行请求的类,此类在RequestManager的构造中创建

public void runRequest(Request request) {
    requests.add(request);
    if (!isPaused) {
        request.begin();//还是交给请求自己处理
    } else {
        pendingRequests.add(request);
    }
}

GenericRequest.begin()

@Override
public void begin() {
    startTime = LogTime.getLogTime();
    if (model == null) {
        onException(null);//显示错误页面
        return;
    }

    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        //执行核心
        onSizeReady(overrideWidth, overrideHeight);
    } else {
        //也会执行onSizeReady
        target.getSize(this);
    }

    if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
        target.onLoadStarted(getPlaceholderDrawable());
    }
}

在onSizeReady内部,请求又转交给了Glide中创建的Engine处理。具体详细,得看我第一篇文章。源码分析

猜你喜欢

转载自blog.csdn.net/wangwei708846696/article/details/83047100