Glide的load()過(guò)程源碼分析

??上一次文章中分析了Glide的with()過(guò)程莱坎,接著來(lái)分析load()過(guò)程。
??在with()方法結(jié)束時(shí)我們得到了RequestManager對(duì)象糙箍,所以這個(gè)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()方法有很多重載的方法。這里只貼出來(lái)了一部分深夯《陡瘢可以從網(wǎng)絡(luò)Url,本地文件等加載資源咕晋,所以load()方法有很多的重載形式雹拄。
這次我們從加載String形式的Url字符串的get()方法開始分析。

load(string)方法中調(diào)用的方法

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()方法中調(diào)用了loadGeneric()方法掌呜。這個(gè)方法的泛型的類型是String.class類型滓玖。在loadGeneric()方法中,

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

首先是這行代碼质蕉,我們來(lái)分析一下這行代碼呢撞。分析一下得到這個(gè)ModelLoader對(duì)象的過(guò)程。
在這行代碼中饰剥,傳入的泛型的類型分別為String.class類型InputStream類型殊霞,然后調(diào)用了Glide的buildStreamModelLoader()方法來(lái)生成了一個(gè)ModelLoader對(duì)象,因?yàn)閭魅氲姆盒偷念愋头謩e為String.class類型汰蓉,所以最后生成的是StreamStringLoader對(duì)象绷蹲,它是實(shí)現(xiàn)了ModelLoader接口的。

  • ModelLoader對(duì)象是用于加載圖片的

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()方法中調(diào)用了

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

一步一步來(lái)分析比规,先看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);
                    }
                   //通過(guò)GlideBuilder類的createGlide()方法來(lái)創(chuàng)建Glide對(duì)象
                    glide = builder.createGlide();
                    for (GlideModule module : modules) {
                        module.registerComponents(applicationContext, glide);
                    }
                }
            }
        }

        return glide;
    }

可以看到在這個(gè)方法中,通過(guò)GlideBuilder類的createGlide()方法來(lái)創(chuàng)建Glide對(duì)象拦英,來(lái)看看創(chuàng)建Glide對(duì)象的過(guò)程蜒什。

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實(shí)現(xiàn)內(nèi)存緩存所使用的
            memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
        }

        if (diskCacheFactory == null) {
           //Glide實(shí)現(xiàn)磁盤緩存所使用的
            diskCacheFactory = new InternalCacheDiskCacheFactory(context);
        }

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

        if (decodeFormat == null) {
            decodeFormat = DecodeFormat.DEFAULT;
        }
       //創(chuàng)建Glide對(duì)象
        return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
    }

里面初始化了很多對(duì)象,并把初始化的東西傳入了Glide的構(gòu)造器中疤估。

Glide的構(gòu)造器中

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

在這個(gè)Glide的這個(gè)構(gòu)造器中就是進(jìn)行一些初始化的操作灾常,這里我只貼出了我們要分析的部分。在Glide的構(gòu)造器中初始化了GenericLoaderFactory類铃拇,并調(diào)用了Glide的register()方法

  • GenericLoaderFactory類:相當(dāng)于一個(gè)工廠钞瀑。這個(gè)類里面保存了各種ModelLoader和各種ModelLoaderFactory,并且通過(guò)保存的各種ModelLoaderFactory來(lái)創(chuàng)建各種ModelLoader慷荔。這個(gè)類之后還要來(lái)分析雕什。

看一下Glide的register()方法的參數(shù)中傳入的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.
        }
    }

這個(gè)靜態(tài)內(nèi)部類就是用來(lái)生成StreamStringLoader()對(duì)象的显晶。那就剛好也看一下ModelLoaderFactory接口贷岸。

ModelLoaderFactory接口

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

可以看到這個(gè)接口的build()方法就是專門用來(lái)生成ModelLoader對(duì)象的。

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()方法磷雇,看一下這個(gè)方法偿警。

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();
        //根據(jù)modelClass來(lái)判斷是否已經(jīng)存在與modelClass對(duì)應(yīng)的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對(duì)應(yīng)的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()方法中所傳來(lái)的factory存入了GenericLoaderFactory類里面的modelClassToResourceFactories中倦春。

創(chuàng)建Glide對(duì)象及Glide對(duì)象的創(chuàng)建過(guò)程中户敬,在Glide的構(gòu)造函數(shù)中都發(fā)生了什么,這個(gè)過(guò)程已經(jīng)結(jié)束了睁本∧蚵回到Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);這行代碼。

Glide的getLoaderFactory()方法

private GenericLoaderFactory getLoaderFactory() {
        return loaderFactory;
    }

這個(gè)loaderFactory就是在Glide初始化時(shí)初始的GenericLoaderFactory對(duì)象呢堰。接著調(diào)用了GenericLoaderFactory類的buildModelLoader(modelClass, resourceClass)方法抄瑟。

GenericLoaderFactory類的buildModelLoader(modelClass, resourceClass)方法

public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
       // 用getCachedLoader()這個(gè)方法得到之前緩存的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()方法來(lái)得到之前緩存的factory
        final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
        if (factory != null) {
            //factory.build()用來(lái)生成相對(duì)應(yīng)的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) {
        //根據(jù)modelClass的到對(duì)應(yīng)的Map
        Map<Class/*Y*/, ModelLoader/*T, Y*/> resourceToLoaders = cachedModelLoaders.get(modelClass);
        ModelLoader/*T, Y*/ result = null;
        if (resourceToLoaders != null) {
           //根據(jù)resourceClass得到對(duì)應(yīng)的ModelLoader
            result = resourceToLoaders.get(resourceClass);
        }
        return result;
    }
private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
       //利用modelClass得到相對(duì)于的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;
    }

這個(gè)過(guò)程分析結(jié)束了枉疼,實(shí)際上就是利用GenericLoaderFactory類得到相應(yīng)的ModelLoader的過(guò)程皮假,在這個(gè)過(guò)程中骂维,我們傳入的modelClass類型為String.Class褪测,傳入的resourceClass類型為InputStream類型侮措,最終得到了StreamStringLoader類型的對(duì)象澄成。
Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);這行代碼分析結(jié)束了,所以最后Glide.buildStreamModelLoader(modelClass, context)這句代碼最后的到了StreamStringLoader類型的對(duì)象歉胶≈嗝回到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);

這個(gè)上面貼的過(guò)程和上面分析的得到StreamStringLoader類型的對(duì)象的過(guò)程類似感耙,所以這個(gè)過(guò)程最后得到的是FileDescriptorUriLoader類型的對(duì)象逃片。
回到loadGeneric()方法,在這個(gè)方法的最后生成了一個(gè)DrawableTypeRequest對(duì)象损离。并將剛剛生成的StreamStringLoader類型的對(duì)象和FileDescriptorUriLoader類型的對(duì)象還有requestTracker, lifecycle,等一起傳入其構(gòu)造器中。
進(jìn)入這個(gè)DrawableTypeRequest類看看哩俭。

DrawableTypeRequest類的構(gòu)造函數(shù)

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類型對(duì)象
        if (transcoder == null) {
            transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
        }
        //2.得到ImageVideoGifDrawableLoadProvider類型對(duì)象
        DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
                resourceClass);
        //3.傳入StreamStringLoader類型的對(duì)象和FileDescriptorUriLoader類型的對(duì)象來(lái)生成ImageVideoModelLoader對(duì)象。
        ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
                fileDescriptorModelLoader);
        //在這個(gè)buildProvider()方法中隙赁,將ImageVideoModelLoader類型的ModelLoader,GlideBitmapDrawableTranscoder類型的ResourceTranscoder厚掷,ImageVideoGifDrawableLoadProvider類型的DataLoadProvider傳入FixedLoadProvider的構(gòu)造器中
        return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
    }
   //在DrawableTypeRequest的構(gòu)造函數(shù)中级解,初始化從父類繼承來(lái)的實(shí)例
    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;
    }
}

先來(lái)分析一下代碼中標(biāo)記的1,2過(guò)程。
1過(guò)程transcoder = glide.buildTranscoder(resourceClass, transcodedClass);調(diào)用了Glide的buildTranscoder()方法勤哗。

Glide的buildTranscoder()方法

private final TranscoderRegistry transcoderRegistry = new TranscoderRegistry();
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
       ......
       //注冊(cè)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()方法所用到的方法如上,可以看到是通過(guò)transcoderRegistry.get(decodedClass, transcodedClass);來(lái)得到ResourceTranscoder對(duì)象的芒划。

  • ResourceTranscoder接口:它是用于對(duì)圖片進(jìn)行轉(zhuǎn)碼的

TranscoderRegistry類中

public class TranscoderRegistry {
    private static final MultiClassKey GET_KEY = new MultiClassKey();
    //這個(gè)Map以MultiClassKey為key,ResourceTranscoder對(duì)象為value.
    private final Map<MultiClassKey, ResourceTranscoder<?, ?>> factories =
            new HashMap<MultiClassKey, ResourceTranscoder<?, ?>>();
//之前在Glide的構(gòu)造方法中已經(jīng)注冊(cè)過(guò)了冬竟。用這個(gè)方法得到之前注冊(cè)的
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中得到注冊(cè)的GlideBitmapDrawableTranscoder
            result = factories.get(GET_KEY);
        }
        if (result == null) {
            throw new IllegalArgumentException("No transcoder registered for " + decodedClass + " and "
                    + transcodedClass);
        }
        return (ResourceTranscoder<Z, R>) result;
    }
}

所以總結(jié)1過(guò)程,傳入的resourceClass, transcodedClass分別為GifBitmapWrapper, GlideDrawable類型缴挖。最后得到的是GifBitmapWrapperDrawableTranscoder對(duì)象苟鸯。GlideBitmapDrawableTranscoder繼承自ResourceTranscoder接口,該接口用于圖片的轉(zhuǎn)碼瘫析。

2過(guò)程類似1過(guò)程砌梆,最后得到的對(duì)象類型為ImageVideoGifDrawableLoadProvider默责,ImageVideoGifDrawableLoadProvider類繼承DataLoadProvider接口。

  • DataLoadProvider接口:用于對(duì)圖片進(jìn)行編解碼的咸包。

再來(lái)看一下標(biāo)記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");
        }
        //傳進(jìn)來(lái)的StreamStringLoader類型的對(duì)象
        this.streamLoader = streamLoader;
        //傳入的FileDescriptorUriLoader類型的對(duì)象
        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對(duì)象是ImageVideoModelLoader類的內(nèi)部類
            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構(gòu)造器的StreamStringLoader類型的對(duì)象和FileDescriptorUriLoader類型的對(duì)象傳入ImageVideoModelLoader的構(gòu)造器中來(lái)生成ImageVideoModelLoader對(duì)象桃序。這個(gè)ImageVideoModelLoader類繼承自ModelLoader接口,在該類的getResourceFetcher()方法中烂瘫,來(lái)分析一下12過(guò)程媒熊。
1過(guò)程

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

streamLoader的類型是StreamStringLoader類坟比,看一下StreamStringLoader類的getResourceFetcher()方法芦鳍。發(fā)現(xiàn)這個(gè)類里面沒(méi)有getResourceFetcher()方法,但是它繼承于StringLoader類葛账,發(fā)現(xiàn)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);
    }

在這個(gè)StringLoader類中的getResourceFetcher()方法的最后返回了uriLoader的getResourceFetcher()方法。這個(gè)uriLoader的類型是HttpUrlGlideUrlLoader籍琳。那進(jìn)入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);
    }

看到在這個(gè)HttpUrlGlideUrlLoader的getResourceFetcher()方法的最后返回了一個(gè)HttpUrlFetcher()對(duì)象。StringLoader類中的getResourceFetcher()方法中最后返回的是一個(gè)HttpUrlFetcher()對(duì)象巩割,即StreamStringLoader類的getResourceFetcher()方法最后得到了一個(gè)HttpUrlFetcher()對(duì)象裙顽。所以1過(guò)程最后得到了一個(gè)HttpUrlFetcher()對(duì)象付燥。
2過(guò)程類似于1過(guò)程宣谈。
回到ImageVideoModelLoader類的getResourceFetcher方法中,最后將得到的HttpUrlFetcher()對(duì)象傳入ImageVideoFetcher()的構(gòu)造器中键科,這個(gè)ImageVideoFetche類是ImageVideoModelLoader類的內(nèi)部類闻丑。

總結(jié)一下,從開始到現(xiàn)在的3個(gè)很重要的接口

  • ModelLoader接口:是用于加載圖片的
  • ResourceTranscoder接口:它是用于對(duì)圖片進(jìn)行轉(zhuǎn)碼的
  • DataLoadProvider接口:用于對(duì)圖片進(jìn)行編解碼的勋颖。

這里還要補(bǔ)充一下嗦嗡,DrawableTypeRequest類里面的asBitmap()方法和asGif()方法。

DrawableTypeRequest類里面的asBitmap()方法

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

asBitmap()方法里面生成了BitmapTypeRequest對(duì)象饭玲,它類似于DrawableTypeRequest侥祭,這個(gè)BitmapTypeRequest的最終的父類也是GenericRequestBuilder。
asGif()方法asBitmap()方法類似茄厘。

回到DrawableTypeRequest類的構(gòu)造函數(shù)中矮冬。
DrawableTypeRequest類的構(gòu)造函數(shù)中又初始化了從父類那里繼承得到的實(shí)例對(duì)象,我們看一下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.
        ......
    }
}

看到這個(gè)類同樣初始化了從父類那里繼承得到的實(shí)例對(duì)象胎署,我們看一下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;
        }
    }
}

在這個(gè)類中窑滞,將DrawableTypeRequest類中生成的FixedLoadProvider類的對(duì)象在構(gòu)造函數(shù)中傳入ChildLoadProvider()的構(gòu)造器中琼牧,所以最后在該類中的loadProvider實(shí)例變量所指向的類型為ChildLoadProvider類型恢筝,ChildLoadProvider也是DataLoadProvider接口的實(shí)現(xiàn)類。

  • GenericRequestBuilder類:這個(gè)類提供了加載各種資源的方法巨坊,是各種資源請(qǐng)求構(gòu)造類的父類撬槽。

好了,從在RequestManager類的loadGeneric()方法中趾撵,創(chuàng)建DrawableTypeRequest對(duì)象恢氯,又分析了很多。
現(xiàn)在回到RequestManager類的load(string)方法中鼓寺。

load(string)方法中

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

在load(string)方法中噪馏,fromString()方法的過(guò)程已經(jīng)分析過(guò)了卵佛,發(fā)現(xiàn)這個(gè)方法最終返回的是DrawableTypeRequest類型的對(duì)象,所以fromString()方法后面調(diào)用的.load()方法,就是DrawableTypeRequest類里面的方法彩扔,但是發(fā)現(xiàn)DrawableTypeRequest類里面根本沒(méi)有l(wèi)oad()方法,所以這個(gè)方法是其父類的方法莹妒。

DrawableRequestBuilder類中

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

調(diào)用了其父類的load()方法铛绰。那就到GenericRequestBuilder類中看看。

GenericRequestBuilder類中

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

這個(gè)model就是load()方法中傳入的String類型的字符串幔虏。
Glide的load()過(guò)程結(jié)束了纺念。這個(gè)分析過(guò)程中分析了很多其他的東西,但是分析的東西都是后面我們into()過(guò)程中要使用的想括,所以寫了很多陷谱。好滴,load()過(guò)程最終調(diào)用了GenericRequestBuilder類的load()方法瑟蜈。

參考

Android圖片加載框架最全解析(二)烟逊,從源碼的角度理解Glide的執(zhí)行流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市铺根,隨后出現(xiàn)的幾起案子宪躯,更是在濱河造成了極大的恐慌,老刑警劉巖位迂,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件访雪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掂林,警方通過(guò)查閱死者的電腦和手機(jī)臣缀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)党饮,“玉大人肝陪,你說(shuō)我怎么就攤上這事⌒趟常” “怎么了氯窍?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵饲常,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我狼讨,道長(zhǎng)贝淤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任政供,我火速辦了婚禮播聪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘布隔。我一直安慰自己离陶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布衅檀。 她就那樣靜靜地躺著招刨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哀军。 梳的紋絲不亂的頭發(fā)上沉眶,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音杉适,去河邊找鬼谎倔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛猿推,可吹牛的內(nèi)容都是我干的片习。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼彤守,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毯侦!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起具垫,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎试幽,沒(méi)想到半個(gè)月后筝蚕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铺坞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年起宽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片济榨。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡坯沪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出擒滑,到底是詐尸還是另有隱情腐晾,我是刑警寧澤叉弦,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站藻糖,受9級(jí)特大地震影響淹冰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜巨柒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一樱拴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧洋满,春花似錦晶乔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至禽最,卻和暖如春腺怯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背川无。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工呛占, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人懦趋。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓晾虑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親仅叫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子帜篇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 《大腦的情緒生活》作者是理查德·戴維森和沙倫·貝格利。 人們每天都會(huì)產(chǎn)生各種各樣的情緒诫咱。但是笙隙,因?yàn)榍榫w發(fā)生在大腦中...
    _劉建宏_閱讀 451評(píng)論 0 1
  • 母親去世后,阿遠(yuǎn)和父親搬離了原來(lái)的住處坎缭。一輛三輪車馱著爺倆所有的家當(dāng)竟痰,冬天的風(fēng)大、刺骨掏呼,像密集的響箭從敗掉的樹林里...
    阿芥閱讀 553評(píng)論 9 5
  • 職場(chǎng)人最繞不開的問(wèn)題是什么憎夷?我相信百分之九十九的回答都是“工資”莽鸿。可以說(shuō)工資就是我們每天勞動(dòng)的價(jià)值體現(xiàn)拾给,誰(shuí)不希望自...
    Vivian思朦閱讀 227評(píng)論 0 1
  • 文/賴世杰 我有一個(gè)調(diào)皮的弟弟祥得,他叫賴俊成兔沃,小名叫俊俊。 俊俊長(zhǎng)得非晨谢Γ可愛(ài)粘拾。頭上有個(gè)小...
    我愛(ài)無(wú)花果閱讀 374評(píng)論 1 2