Glide的load()过程源码分析

  上一次文章中分析了Glide的with()过程,接着来分析load()过程。
  在with()方法结束时我们得到了RequestManager对象,所以这个load()方法就是RequestManager类中的方法。

public DrawableTypeRequest<String> load(String string) {
        return (DrawableTypeRequest<String>) fromString().load(string);
    }
public DrawableTypeRequest<Uri> load(Uri uri) {
        return (DrawableTypeRequest<Uri>) fromUri().load(uri);
    }
 public DrawableTypeRequest<File> load(File file) {
        return (DrawableTypeRequest<File>) fromFile().load(file);
    }
 public DrawableTypeRequest<Integer> load(Integer resourceId) {
        return (DrawableTypeRequest<Integer>) fromResource().load(resourceId);
    }

  load()方法有很多重载的方法。这里只贴出来了一部分。可以从网络Url,本地文件等加载资源,所以load()方法有很多的重载形式。
这次我们从加载String形式的Url字符串的get()方法开始分析。

load(string)方法中调用的方法

public DrawableTypeRequest<String> fromString() {
        return loadGeneric(String.class);
    }
private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
        ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
        ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
                Glide.buildFileDescriptorModelLoader(modelClass, context);
        if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
            throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
                    + " which there is a registered ModelLoader, if you are using a custom model, you must first call"
                    + " Glide#register with a ModelLoaderFactory for your custom model class");
        }

        return optionsApplier.apply(
                new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                        glide, requestTracker, lifecycle, optionsApplier));
    }

  在fromString()方法中调用了loadGeneric()方法。这个方法的泛型的类型是String.class类型。在loadGeneric()方法中,

ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);

首先是这行代码,我们来分析一下这行代码。分析一下得到这个ModelLoader对象的过程。
在这行代码中,传入的泛型的类型分别为String.class类型InputStream类型,然后调用了Glide的buildStreamModelLoader()方法来生成了一个ModelLoader对象,因为传入的泛型的类型分别为String.class类型,所以最后生成的是StreamStringLoader对象,它是实现了ModelLoader接口的。

  • ModelLoader对象是用于加载图片的

Glide类里面的方法

public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
        return buildModelLoader(modelClass, InputStream.class, context);
    }
public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass,
            Context context) {
         if (modelClass == null) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Unable to load null model, setting placeholder only");
            }
            return null;
        }
        return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
    }

modelClass类型为String.class,resourceClass的类型为InputStream.class。然后在buildModelLoader()方法中调用了

Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);

一步一步来分析,先看Glide的 get(Context context)方法

public static Glide get(Context context) {
        if (glide == null) {
            synchronized (Glide.class) {
                if (glide == null) {
                    Context applicationContext = context.getApplicationContext();
                    List<GlideModule> modules = new ManifestParser(applicationContext).parse();

                    GlideBuilder builder = new GlideBuilder(applicationContext);
                    for (GlideModule module : modules) {
                        module.applyOptions(applicationContext, builder);
                    }
                   //通过GlideBuilder类的createGlide()方法来创建Glide对象
                    glide = builder.createGlide();
                    for (GlideModule module : modules) {
                        module.registerComponents(applicationContext, glide);
                    }
                }
            }
        }

        return glide;
    }

可以看到在这个方法中,通过GlideBuilder类的createGlide()方法来创建Glide对象,来看看创建Glide对象的过程。

GlideBuilder类createGlide()方法

private final Context context;

    private Engine engine;
    private BitmapPool bitmapPool;
    private MemoryCache memoryCache;
    private ExecutorService sourceService;
    private ExecutorService diskCacheService;
    private DecodeFormat decodeFormat;
    private DiskCache.Factory diskCacheFactory;

    public GlideBuilder(Context context) {
        this.context = context.getApplicationContext();
    }
Glide createGlide() {
        if (sourceService == null) {
            final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
            sourceService = new FifoPriorityThreadPoolExecutor(cores);
        }
        if (diskCacheService == null) {
            diskCacheService = new FifoPriorityThreadPoolExecutor(1);
        }

        MemorySizeCalculator calculator = new MemorySizeCalculator(context);
        if (bitmapPool == null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                int size = calculator.getBitmapPoolSize();
                bitmapPool = new LruBitmapPool(size);
            } else {
                bitmapPool = new BitmapPoolAdapter();
            }
        }

        if (memoryCache == null) {
           //Glide实现内存缓存所使用的
            memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
        }

        if (diskCacheFactory == null) {
           //Glide实现磁盘缓存所使用的
            diskCacheFactory = new InternalCacheDiskCacheFactory(context);
        }

        if (engine == null) {
            engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
        }

        if (decodeFormat == null) {
            decodeFormat = DecodeFormat.DEFAULT;
        }
       //创建Glide对象
        return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
    }

里面初始化了很多对象,并把初始化的东西传入了Glide的构造器中。

Glide的构造器中

private final GenericLoaderFactory loaderFactory;
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
        ......
        loaderFactory = new GenericLoaderFactory(context);
        ......
        register(String.class, InputStream.class, new StreamStringLoader.Factory());
    }

在这个Glide的这个构造器中就是进行一些初始化的操作,这里我只贴出了我们要分析的部分。在Glide的构造器中初始化了GenericLoaderFactory类,并调用了Glide的register()方法

  • GenericLoaderFactory类:相当于一个工厂。这个类里面保存了各种ModelLoader和各种ModelLoaderFactory,并且通过保存的各种ModelLoaderFactory来创建各种ModelLoader。这个类之后还要来分析。

看一下Glide的register()方法的参数中传入的new StreamStringLoader.Factory()。

StreamStringLoader.Factory()

 public static class Factory implements ModelLoaderFactory<String, InputStream> {
        @Override
        public ModelLoader<String, InputStream> build(Context context, GenericLoaderFactory factories) {
            return new StreamStringLoader(factories.buildModelLoader(Uri.class, InputStream.class));
        }

        @Override
        public void teardown() {
            // Do nothing.
        }
    }

这个静态内部类就是用来生成StreamStringLoader()对象的。那就刚好也看一下ModelLoaderFactory接口。

ModelLoaderFactory接口

public interface ModelLoaderFactory<T, Y> {
    ModelLoader<T, Y> build(Context context, GenericLoaderFactory factories);
    void teardown();
}

可以看到这个接口的build()方法就是专门用来生成ModelLoader对象的。

Glide的register()方法

public <T, Y> void register(Class<T> modelClass, Class<Y> resourceClass, ModelLoaderFactory<T, Y> factory) {
        ModelLoaderFactory<T, Y> removed = loaderFactory.register(modelClass, resourceClass, factory);
        if (removed != null) {
            removed.teardown();
        }
    }

在register()方法中GenericLoaderFactory的register()方法,看一下这个方法。

GenericLoaderFactory里面的register()方法

//缓存各种ModelLoaderFactory
private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/>> modelClassToResourceFactories =
            new HashMap<Class, Map<Class, ModelLoaderFactory>>();
//缓存各种ModelLoader
private final Map<Class/*T*/, Map<Class/*Y*/, ModelLoader/*T, Y*/>> cachedModelLoaders =
            new HashMap<Class, Map<Class, ModelLoader>>();
public synchronized <T, Y> ModelLoaderFactory<T, Y> register(Class<T> modelClass, Class<Y> resourceClass,
            ModelLoaderFactory<T, Y> factory) {
        cachedModelLoaders.clear();
        //根据modelClass来判断是否已经存在与modelClass对应的ModelLoaderFactory的Map
        Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
        if (resourceToFactories == null) {
            resourceToFactories = new HashMap<Class/*Y*/, ModelLoaderFactory/*T, Y*/>();
            //以modelClass为key,将新建的Map集合放入modelClassToResourceFactories中
            modelClassToResourceFactories.put(modelClass, resourceToFactories);
        }
         //以resourceClass为key,将传入的factory放入与modelClass对应的Map中
        ModelLoaderFactory/*T, Y*/ previous = resourceToFactories.put(resourceClass, factory);

        if (previous != null) {
            for (Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> factories : modelClassToResourceFactories.values()) {
                if (factories.containsValue(previous)) {
                    previous = null;
                    break;
                }
            }
        }

        return previous;
    }

GenericLoaderFactory里面的register()方法就是将Glide的register()方法中所传来的factory存入了GenericLoaderFactory类里面的modelClassToResourceFactories中。

创建Glide对象及Glide对象的创建过程中,在Glide的构造函数中都发生了什么,这个过程已经结束了。回到Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);这行代码。

Glide的getLoaderFactory()方法

private GenericLoaderFactory getLoaderFactory() {
        return loaderFactory;
    }

这个loaderFactory就是在Glide初始化时初始的GenericLoaderFactory对象。接着调用了GenericLoaderFactory类的buildModelLoader(modelClass, resourceClass)方法。

GenericLoaderFactory类的buildModelLoader(modelClass, resourceClass)方法

public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
       // 用getCachedLoader()这个方法得到之前缓存的ModelLoader
        ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
        if (result != null) {
            if (NULL_MODEL_LOADER.equals(result)) {
                return null;
            } else {
                return result;
            }
        }
        //如果得到的ModelLoader为null,用getFactory()方法来得到之前缓存的factory
        final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
        if (factory != null) {
            //factory.build()用来生成相对应的ModleLoader
            result = factory.build(context, this);
            //缓存生成的ModleLoader
            result = factory.build(context, this);
            cacheModelLoader(modelClass, resourceClass, result);
        } else {
            cacheNullLoader(modelClass, resourceClass);
        }
        return result;
    }
private <T, Y> ModelLoader<T, Y> getCachedLoader(Class<T> modelClass, Class<Y> resourceClass) {
        //根据modelClass的到对应的Map
        Map<Class/*Y*/, ModelLoader/*T, Y*/> resourceToLoaders = cachedModelLoaders.get(modelClass);
        ModelLoader/*T, Y*/ result = null;
        if (resourceToLoaders != null) {
           //根据resourceClass得到对应的ModelLoader
            result = resourceToLoaders.get(resourceClass);
        }
        return result;
    }
private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
       //利用modelClass得到相对于的Map
        Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
        ModelLoaderFactory/*T, Y*/ result = null;
        if (resourceToFactories != null) {
           //利用resourceClass得到之前缓存的Factory
            result = resourceToFactories.get(resourceClass);
        }

        if (result == null) {
            for (Class<? super T> registeredModelClass : modelClassToResourceFactories.keySet()) {
                if (registeredModelClass.isAssignableFrom(modelClass)) {
                    Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> currentResourceToFactories =
                            modelClassToResourceFactories.get(registeredModelClass);
                    if (currentResourceToFactories != null) {
                        result = currentResourceToFactories.get(resourceClass);
                        if (result != null) {
                            break;
                        }
                    }
                }
            }
        }

        return result;
    }

这个过程分析结束了,实际上就是利用GenericLoaderFactory类得到相应的ModelLoader的过程,在这个过程中,我们传入的modelClass类型为String.Class,传入的resourceClass类型为InputStream类型,最终得到了StreamStringLoader类型的对象。
Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);这行代码分析结束了,所以最后Glide.buildStreamModelLoader(modelClass, context)这句代码最后的到了StreamStringLoader类型的对象。回到loadGeneric()方法,再贴一下。

private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
        ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
        ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
                Glide.buildFileDescriptorModelLoader(modelClass, context);
        if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
            throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
                    + " which there is a registered ModelLoader, if you are using a custom model, you must first call"
                    + " Glide#register with a ModelLoaderFactory for your custom model class");
        }

        return optionsApplier.apply(
                new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                        glide, requestTracker, lifecycle, optionsApplier));
    }
ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
                Glide.buildFileDescriptorModelLoader(modelClass, context);

这个上面贴的过程和上面分析的得到StreamStringLoader类型的对象的过程类似,所以这个过程最后得到的是FileDescriptorUriLoader类型的对象。
回到loadGeneric()方法,在这个方法的最后生成了一个DrawableTypeRequest对象。并将刚刚生成的StreamStringLoader类型的对象和FileDescriptorUriLoader类型的对象还有requestTracker, lifecycle,等一起传入其构造器中。
进入这个DrawableTypeRequest类看看。

DrawableTypeRequest类的构造函数

public class DrawableTypeRequest<ModelType> extends DrawableRequestBuilder<ModelType> implements DownloadOptions {
private final ModelLoader<ModelType, InputStream> streamModelLoader;
    private final ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader;
    private final RequestManager.OptionsApplier optionsApplier;
   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;
        }
        //1.得到GifBitmapWrapperDrawableTranscoder类型对象
        if (transcoder == null) {
            transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
        }
        //2.得到ImageVideoGifDrawableLoadProvider类型对象
        DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
                resourceClass);
        //3.传入StreamStringLoader类型的对象和FileDescriptorUriLoader类型的对象来生成ImageVideoModelLoader对象。
        ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
                fileDescriptorModelLoader);
        //在这个buildProvider()方法中,将ImageVideoModelLoader类型的ModelLoader,GlideBitmapDrawableTranscoder类型的ResourceTranscoder,ImageVideoGifDrawableLoadProvider类型的DataLoadProvider传入FixedLoadProvider的构造器中
        return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
    }
   //在DrawableTypeRequest的构造函数中,初始化从父类继承来的实例
    DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
            ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
            RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
        super(context, modelClass,
                buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, GifBitmapWrapper.class,
                        GlideDrawable.class, null),
                glide, requestTracker, lifecycle);
      this.streamModelLoader = streamModelLoader;
        this.fileDescriptorModelLoader = fileDescriptorModelLoader;
        this.optionsApplier = optionsApplier;
    }
}

先来分析一下代码中标记的1,2过程。
1过程transcoder = glide.buildTranscoder(resourceClass, transcodedClass);调用了Glide的buildTranscoder()方法。

Glide的buildTranscoder()方法

private final TranscoderRegistry transcoderRegistry = new TranscoderRegistry();
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
       ......
       //注册GlideBitmapDrawableTranscoder到transcoderRegistry
       transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
                new GifBitmapWrapperDrawableTranscoder(
                        new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));
     ......
    }
<Z, R> ResourceTranscoder<Z, R> buildTranscoder(Class<Z> decodedClass, Class<R> transcodedClass) {
        return transcoderRegistry.get(decodedClass, transcodedClass);
    }

Glide的buildTranscoder()方法所用到的方法如上,可以看到是通过transcoderRegistry.get(decodedClass, transcodedClass);来得到ResourceTranscoder对象的。

  • ResourceTranscoder接口:它是用于对图片进行转码的

TranscoderRegistry类中

public class TranscoderRegistry {
    private static final MultiClassKey GET_KEY = new MultiClassKey();
    //这个Map以MultiClassKey为key,ResourceTranscoder对象为value.
    private final Map<MultiClassKey, ResourceTranscoder<?, ?>> factories =
            new HashMap<MultiClassKey, ResourceTranscoder<?, ?>>();
//之前在Glide的构造方法中已经注册过了。用这个方法得到之前注册的
public <Z, R> ResourceTranscoder<Z, R> get(Class<Z> decodedClass, Class<R> transcodedClass) {
        if (decodedClass.equals(transcodedClass)) {
            return (ResourceTranscoder<Z, R>) UnitTranscoder.get();
        }
        final ResourceTranscoder<?, ?> result;
        synchronized (GET_KEY) {
            GET_KEY.set(decodedClass, transcodedClass);
            //利用MultiClassKey从Map中得到注册的GlideBitmapDrawableTranscoder
            result = factories.get(GET_KEY);
        }
        if (result == null) {
            throw new IllegalArgumentException("No transcoder registered for " + decodedClass + " and "
                    + transcodedClass);
        }
        return (ResourceTranscoder<Z, R>) result;
    }
}

所以总结1过程,传入的resourceClass, transcodedClass分别为GifBitmapWrapper, GlideDrawable类型。最后得到的是GifBitmapWrapperDrawableTranscoder对象。GlideBitmapDrawableTranscoder继承自ResourceTranscoder接口,该接口用于图片的转码。

2过程类似1过程,最后得到的对象类型为ImageVideoGifDrawableLoadProvider,ImageVideoGifDrawableLoadProvider类继承DataLoadProvider接口。

  • DataLoadProvider接口:用于对图片进行编解码的。

再来看一下标记3
ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
fileDescriptorModelLoader);

ImageVideoModelLoader类

public class ImageVideoModelLoader<A> implements ModelLoader<A, ImageVideoWrapper> {
    private final ModelLoader<A, InputStream> streamLoader;
    private final ModelLoader<A, ParcelFileDescriptor> fileDescriptorLoader;

    public ImageVideoModelLoader(ModelLoader<A, InputStream> streamLoader,
            ModelLoader<A, ParcelFileDescriptor> fileDescriptorLoader) {
        if (streamLoader == null && fileDescriptorLoader == null) {
            throw new NullPointerException("At least one of streamLoader and fileDescriptorLoader must be non null");
        }
        //传进来的StreamStringLoader类型的对象
        this.streamLoader = streamLoader;
        //传入的FileDescriptorUriLoader类型的对象
        this.fileDescriptorLoader = fileDescriptorLoader;
    }
@Override
    public DataFetcher<ImageVideoWrapper> getResourceFetcher(A model, int width, int height) {
        DataFetcher<InputStream> streamFetcher = null;
        if (streamLoader != null) {
            //1.
            streamFetcher = streamLoader.getResourceFetcher(model, width, height);
        }
        DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher = null;
        if (fileDescriptorLoader != null) {
            //2.
            fileDescriptorFetcher = fileDescriptorLoader.getResourceFetcher(model, width, height);
        }

        if (streamFetcher != null || fileDescriptorFetcher != null) {
            //返回的ImageVideoFetcher对象是ImageVideoModelLoader类的内部类
            return new ImageVideoFetcher(streamFetcher, fileDescriptorFetcher);
        } else {
            return null;
        }
    }

    static class ImageVideoFetcher implements DataFetcher<ImageVideoWrapper> {
        private final DataFetcher<InputStream> streamFetcher;
        private final DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher;

        public ImageVideoFetcher(DataFetcher<InputStream> streamFetcher,
                DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher) {
            this.streamFetcher = streamFetcher;
            this.fileDescriptorFetcher = fileDescriptorFetcher;
        }

        @SuppressWarnings("resource")
        // @see ModelLoader.loadData
        @Override
        public ImageVideoWrapper loadData(Priority priority) throws Exception {
            InputStream is = null;
            if (streamFetcher != null) {
                try {
                    is = streamFetcher.loadData(priority);
                } catch (Exception e) {
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG, "Exception fetching input stream, trying ParcelFileDescriptor", e);
                    }
                    if (fileDescriptorFetcher == null) {
                        throw e;
                    }
                }
            }
            ParcelFileDescriptor fileDescriptor = null;
            if (fileDescriptorFetcher != null) {
                try {
                    fileDescriptor = fileDescriptorFetcher.loadData(priority);
                } catch (Exception e) {
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG, "Exception fetching ParcelFileDescriptor", e);
                    }
                    if (is == null) {
                        throw e;
                    }
                }
            }
            return new ImageVideoWrapper(is, fileDescriptor);
        }
    }
}

将传入DrawableTypeRequest构造器的StreamStringLoader类型的对象和FileDescriptorUriLoader类型的对象传入ImageVideoModelLoader的构造器中来生成ImageVideoModelLoader对象。这个ImageVideoModelLoader类继承自ModelLoader接口,在该类的getResourceFetcher()方法中,来分析一下12过程。
1过程

streamFetcher = streamLoader.getResourceFetcher(model, width, height);

streamLoader的类型是StreamStringLoader类,看一下StreamStringLoader类的getResourceFetcher()方法。发现这个类里面没有getResourceFetcher()方法,但是它继承于StringLoader类,发现getResourceFetcher()方法就在StringLoader类中。

StringLoader类中的getResourceFetcher()方法

private final ModelLoader<Uri, T> uriLoader;
public DataFetcher<T> getResourceFetcher(String model, int width, int height) {
        Uri uri;
        if (TextUtils.isEmpty(model)) {
            return null;
        } else if (model.startsWith("/")) {
            uri = toFileUri(model);
        } else {
            uri = Uri.parse(model);
            final String scheme = uri.getScheme();
            if (scheme == null) {
                uri = toFileUri(model);
            }
        }

        return uriLoader.getResourceFetcher(uri, width, height);
    }

在这个StringLoader类中的getResourceFetcher()方法的最后返回了uriLoader的getResourceFetcher()方法。这个uriLoader的类型是HttpUrlGlideUrlLoader。那进入HttpUrlGlideUrlLoader的getResourceFetcher()方法。

HttpUrlGlideUrlLoader的getResourceFetcher()方法

public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {
        // GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time spent parsing urls.
        GlideUrl url = model;
        if (modelCache != null) {
            url = modelCache.get(model, 0, 0);
            if (url == null) {
                modelCache.put(model, 0, 0, model);
                url = model;
            }
        }
        return new HttpUrlFetcher(url);
    }

看到在这个HttpUrlGlideUrlLoader的getResourceFetcher()方法的最后返回了一个HttpUrlFetcher()对象。StringLoader类中的getResourceFetcher()方法中最后返回的是一个HttpUrlFetcher()对象,即StreamStringLoader类的getResourceFetcher()方法最后得到了一个HttpUrlFetcher()对象。所以1过程最后得到了一个HttpUrlFetcher()对象。
2过程类似于1过程。
回到ImageVideoModelLoader类的getResourceFetcher方法中,最后将得到的HttpUrlFetcher()对象传入ImageVideoFetcher()的构造器中,这个ImageVideoFetche类是ImageVideoModelLoader类的内部类。

总结一下,从开始到现在的3个很重要的接口

  • ModelLoader接口:是用于加载图片的
  • ResourceTranscoder接口:它是用于对图片进行转码的
  • DataLoadProvider接口:用于对图片进行编解码的。

这里还要补充一下,DrawableTypeRequest类里面的asBitmap()方法和asGif()方法。

DrawableTypeRequest类里面的asBitmap()方法

public BitmapTypeRequest<ModelType> asBitmap() {
        return optionsApplier.apply(new BitmapTypeRequest<ModelType>(this, streamModelLoader,
                fileDescriptorModelLoader, optionsApplier));
    }

asBitmap()方法里面生成了BitmapTypeRequest对象,它类似于DrawableTypeRequest,这个BitmapTypeRequest的最终的父类也是GenericRequestBuilder。
asGif()方法asBitmap()方法类似。

回到DrawableTypeRequest类的构造函数中。
DrawableTypeRequest类的构造函数中又初始化了从父类那里继承得到的实例对象,我们看一下DrawableTypeRequest类的父类。

DrawableRequestBuilder类

public class DrawableRequestBuilder<ModelType>
        extends GenericRequestBuilder<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable>
        implements BitmapOptions, DrawableOptions {

    DrawableRequestBuilder(Context context, Class<ModelType> modelClass,
            LoadProvider<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable> loadProvider, Glide glide,
            RequestTracker requestTracker, Lifecycle lifecycle) {
        super(context, modelClass, loadProvider, GlideDrawable.class, glide, requestTracker, lifecycle);
        // Default to animating.
        ......
    }
}

看到这个类同样初始化了从父类那里继承得到的实例对象,我们看一下DrawableRequestBuilder类的父类。

GenericRequestBuilder类

public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
    private ChildLoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider;

    GenericRequestBuilder(LoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider,
            Class<TranscodeType> transcodeClass, GenericRequestBuilder<ModelType, ?, ?, ?> other) {
        this(other.context, other.modelClass, loadProvider, transcodeClass, other.glide, other.requestTracker,
                other.lifecycle);
        ......
    }

    GenericRequestBuilder(Context context, Class<ModelType> modelClass,
            LoadProvider<ModelType, DataType, ResourceType, TranscodeType> loadProvider,
            Class<TranscodeType> transcodeClass, Glide glide, RequestTracker requestTracker, Lifecycle lifecycle) {
        this.loadProvider = loadProvider != null
                ? new ChildLoadProvider<ModelType, DataType, ResourceType, TranscodeType>(loadProvider) : null;
        }
    }
}

在这个类中,将DrawableTypeRequest类中生成的FixedLoadProvider类的对象在构造函数中传入ChildLoadProvider()的构造器中,所以最后在该类中的loadProvider实例变量所指向的类型为ChildLoadProvider类型,ChildLoadProvider也是DataLoadProvider接口的实现类。

  • GenericRequestBuilder类:这个类提供了加载各种资源的方法,是各种资源请求构造类的父类。

好了,从在RequestManager类的loadGeneric()方法中,创建DrawableTypeRequest对象,又分析了很多。
现在回到RequestManager类的load(string)方法中。

load(string)方法中

public DrawableTypeRequest<String> load(String string) {
        return (DrawableTypeRequest<String>) fromString().load(string);
    }

在load(string)方法中,fromString()方法的过程已经分析过了,发现这个方法最终返回的是DrawableTypeRequest类型的对象,所以fromString()方法后面调用的.load()方法,就是DrawableTypeRequest类里面的方法,但是发现DrawableTypeRequest类里面根本没有load()方法,所以这个方法是其父类的方法。

DrawableRequestBuilder类中

public DrawableRequestBuilder<ModelType> load(ModelType model) {
        super.load(model);
        return this;
    }

调用了其父类的load()方法。那就到GenericRequestBuilder类中看看。

GenericRequestBuilder类中

 public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> load(ModelType model) {
        this.model = model;
        isModelSet = true;
        return this;
    }

这个model就是load()方法中传入的String类型的字符串。
Glide的load()过程结束了。这个分析过程中分析了很多其他的东西,但是分析的东西都是后面我们into()过程中要使用的,所以写了很多。好滴,load()过程最终调用了GenericRequestBuilder类的load()方法。

参考

Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

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

推荐阅读更多精彩内容

  • 《大脑的情绪生活》作者是理查德·戴维森和沙伦·贝格利。 人们每天都会产生各种各样的情绪。但是,因为情绪发生在大脑中...
    _刘建宏_阅读 451评论 0 1
  • 母亲去世后,阿远和父亲搬离了原来的住处。一辆三轮车驮着爷俩所有的家当,冬天的风大、刺骨,像密集的响箭从败掉的树林里...
    阿芥阅读 548评论 9 5
  • 职场人最绕不开的问题是什么?我相信百分之九十九的回答都是“工资”。可以说工资就是我们每天劳动的价值体现,谁不希望自...
    Vivian思朦阅读 223评论 0 1
  • 文/赖世杰 我有一个调皮的弟弟,他叫赖俊成,小名叫俊俊。 俊俊长得非常可爱。头上有个小...
    我爱无花果阅读 369评论 1 2