美文网首页
Glide源码分析执行流程

Glide源码分析执行流程

作者: 有没有口罩给我一个 | 来源:发表于2019-04-28 00:55 被阅读0次

    上一篇讲了Glide源码分析之Glide和RequestManager构建过程,有兴趣可以去看一下,这篇我从头到尾又重新讲解Glide从构建到请求网络资源的整个过程,先看一下图,这张图是看源码记录的,不可能全部流程都记下来,这张图只是把整个流程涉及到的比较重要的方法给画出来。

    Glide优势:

    1、可配置度高,自适应度高;
    2、支持多种数据源,本地、网络、assets、gif;
    3、高效缓存,支持memory和diskp图片缓存,默认二级缓存;
    4、使用BitmapPool高效处理Bitmap,避免频繁GC;
    5、图片加载过程可以监听,我们项目中使用了OkHttp作为Glide的网络层监听下载图片进度;
    6、生命周期,Glide绑定Activity的生命周期;

    Glide网络执行流程图.png

    从图中看可能要分几个模块讲,按照图中的步骤分类讲解,分为:1、2、3、4、5、6、7、8、9,尽量详细,当然由于篇幅的原因,仅仅讲解Glide请求网络的过程,像缓存、编解码这些基本是不会讲解,不过后面会分模块功能讲解。

    1、Glide的初始化

    Glide.with:

    public static RequestManager with(FragmentActivity activity) {
        //第一步是构建RequestManagerRetriever和创建Glide,之后调用getRetriever方法
        RequestManagerRetriever requestManagerRetriever = getRetriever(activity);
        RequestManager requestManager = requestManagerRetriever.get(activity);
        return requestManager;
    }
    
    
    @NonNull
    private static RequestManagerRetriever getRetriever(@Nullable Context context) {
        return Glide.get(context).getRequestManagerRetriever();
    }
    
    public static Glide get(@NonNull Context context) {
        if (glide == null) {
            synchronized (Glide.class) {
                if (glide == null) {
                    checkAndInitializeGlide(context);
                }
            }
        }
        return glide;
    }
    

    可以看到在with方法中又调用getRetriever方法之后又调用get方法,其实真正做创建和初始化的操作在initializeGlide方法中

       private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
        //Application
        Context applicationContext = context.getApplicationContext();
    
    
        GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
        List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    
        //是不是在Manifest注册了,在4.0之前就是使用了Manifest自定Module
        if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
            manifestModules = new ManifestParser(applicationContext).parse();
        }
    
        //4.0之后使用了注解的方式,但是Manifest还没有废弃
        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;
                }
     
                }
                iterator.remove();
            }
        }
        //获取RequestManager工程
        RequestManagerRetriever.RequestManagerFactory factory = annotationGeneratedModule != null ? annotationGeneratedModule.getRequestManagerFactory() : null;
        //将RequestManager工厂注入Builder
        builder.setRequestManagerFactory(factory);
    
        // 自定义Module,可更改Glide配置
        for (com.bumptech.glide.module.GlideModule module : manifestModules) {
            module.applyOptions(applicationContext, builder);
        }
    
        // 自定义Module,可更改Glide配置
        if (annotationGeneratedModule != null) {
            annotationGeneratedModule.applyOptions(applicationContext, builder);
        }
    
        //通过Builder创建Glide
        Glide glide = builder.build(applicationContext);
    
        //manifest注册组件
        for (com.bumptech.glide.module.GlideModule module : manifestModules) {
            try {
                module.registerComponents(applicationContext, glide, glide.registry);
            } catch (AbstractMethodError e) {
            }
        }
    
        // 注解生成并注册组件
        if (annotationGeneratedModule != null) {
            annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
        }
    
        // 内存监控
        applicationContext.registerComponentCallbacks(glide);
        //最后赋值
        Glide.glide = glide;
    }
    

    在initializeGlide方法中主要有几点:

    • 根据注解获取各种组件和自定义模块之类的东西

      annotationGeneratedModule.applyOptions(applicationContext, builder);
      
      //通过Builder创建Glide,注意这里为什么要把这段代码写在注册组件和自定义模块之间
        Glide glide = builder.build(applicationContext);
      
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
      
    • 最后将RequestManagerFactory注入GlideBiulder中:

      //获取RequestManager工程
        RequestManagerRetriever.RequestManagerFactory factory = annotationGeneratedModule != null ? annotationGeneratedModule.getRequestManagerFactory() : null;
        //将RequestManager工厂注入Builder
        builder.setRequestManagerFactory(factory);
      

    加下来分析一下: Glide glide = builder.build(applicationContext);

    Glide build(@NonNull Context context) {
        //一般都全部判断是否为null,所以我们在自定义Module时,重写applyOptions方法,可更改配置不使用默认的配置
        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);
        }
    
        // 在Glide.java文件中 builder.setRequestManagerFactory(factory)
        // requestManagerRetriever主要是检查RequestManager
        RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(requestManagerFactory);
    
        return new Glide(
                context,
                engine,
                memoryCache,
                bitmapPool,
                arrayPool,
                requestManagerRetriever,
                connectivityMonitorFactory,
                logLevel,
                defaultRequestOptions.lock(),
                defaultTransitionOptions,
                defaultRequestListeners,
                isLoggingRequestOriginsEnabled);
    }
    

    这段代码很多,不过逻辑是通简单的;无非就是各种线程池的构建和RequestManagerRetriever的创建还有Engine的创建这个比较重要,管理者整个Glide的资源的工作都是Engine做的。

    2、创建RequestManager和生命周期的关联

    RequestManager requestManager = requestManagerRetriever.get(activity);

    在with方法中调用了requestManagerRetriever.get(activity)方法,进去瞄一眼:

    public RequestManager get(@NonNull FragmentActivity activity) {
        if (Util.isOnBackgroundThread()) {
            return get(activity.getApplicationContext());
        } else {
            assertNotDestroyed(activity);
            FragmentManager fm = activity.getSupportFragmentManager();
            return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
        }
    }
    

    实际上get方法有很多重载的方法,其实逻辑是一样的,暂时不管,先看看supportFragmentGet方法:

        private RequestManager supportFragmentGet(@NonNull Context context, @NonNull FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
        //1 获取Fragment
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
        //尝试在Fragment中获取RequestManager
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {//不存在
            Glide glide = Glide.get(context);
            //创建RequestManager
            requestManager = factory.build(glide,
                    current.getGlideLifecycle(),//生命周期的回调
                    current.getRequestManagerTreeNode(), context);
            //并保存到Fragment中
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }
    

    看到1了吗:

    private SupportRequestManagerFragment getSupportRequestManagerFragment(@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    
        //检索是否存在SupportRequestManagerFragment,如果不存在则创建一个Fragmment并添加到缓存中
        SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
        if (current == null) {//不存在
            //尝试从缓存中读取
            current = pendingSupportRequestManagerFragments.get(fm);
            if (current == null) {//还是不存在
                //那么就创建一个新的Fragment
                current = new SupportRequestManagerFragment();
                current.setParentFragmentHint(parentHint);
                if (isParentVisible) {
                    current.getGlideLifecycle().onStart();
                }
                //添加到缓存中
                pendingSupportRequestManagerFragments.put(fm, current);
                fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
    //绑定成功后则从pendingRequestManagerFragments移除fragment。这里的pendingRequestManagerFragments主要是防止fragment重复创建,因为每个activity必须对应一个唯一的fragment。
                handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
            }
        }
        return current;
    }
    

    检索是否存在SupportRequestManagerFragment,如果不存在则创建一个Fragmment并添加到缓存中, 因为Glide使用一个隐藏的Fargment作为监听声明周期作用,至于为什么添加Fragment又移除,我在谷歌查了一下说是这里的pendingRequestManagerFragments主要是防止fragment重复创建,因为每个activity必须对应一个唯一的fragment。

    经过上面的步骤基本上就是Glide创建和初始化,并创建了RequestManager,并将RequestManager保存至Fragment中,以及关联生命周期。

    3、接下来就是使用load()和into()方法:

     public RequestBuilder<Drawable> load(@Nullable String string) {
        return asDrawable().load(string);
    }
    
    @NonNull
    @CheckResult
    public <ResourceType> RequestBuilder<ResourceType> as(
            @NonNull Class<ResourceType> resourceClass) {
        return new RequestBuilder<>(glide, this, resourceClass, context);
    }
    

    实际上load方法主要是构建RequestBuilder,接着没什么好说的,看一下into

    private <Y extends Target<TranscodeType>> Y into(@NonNull Y target, @Nullable RequestListener<TranscodeType> targetListener, BaseRequestOptions<?> options, Executor callbackExecutor) {
        Preconditions.checkNotNull(target);
    
        /**
         * 如果不先调用load就抛这个异常
         */
        if (!isModelSet) {
            throw new IllegalArgumentException("You must call #load() before calling #into()");
        }
    
    
        //构建请求会返回一个SingleRequest
        Request request = buildRequest(target, targetListener, options, callbackExecutor);
        Request previous = target.getRequest();
    
        //上一个请求的处理,就是上一个请求由于某种原因暂停请求
        if (request.isEquivalentTo(previous) && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
            request.recycle();
            if (!Preconditions.checkNotNull(previous).isRunning()) {
                previous.begin();
            }
            return target;
        }
        requestManager.clear(target);
        target.setRequest(request);//target绑定一个请求
        // 真正开始请求的地方
        requestManager.track(target, request);
        return target;
    }
    

    其实这段代码看注释应该就能明白大体是做什么的,主要是如果请求暂停,就开始请求,比较重要的是requestManager.track(target, request)这段代码是要开始新请求,Glide加载图片的整个触发点。

     synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
        targetTracker.track(target);
        requestTracker.runRequest(request);
    }
    

    走了那么久,终于看到runRequest(),运行请求?那就看一下。

    /**
     * 开始追踪请求
     * <p>
     * Starts tracking the given request.
     */
    public void runRequest(@NonNull Request request) {
        requests.add(request);
        if (!isPaused) {
            //如果暂停就开始请求
            request.begin();
        } else {
            request.clear();
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "Paused, delaying request");
            }
            //待处理的请求
            pendingRequests.add(request);
        }
    }
    

    还是没看到什么东西, 那就看一下request.begin(),实际上应该看SingleRequest的begin方法。

    @Override
    public synchronized void begin() {
        if (model == null) {
            if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
                width = overrideWidth;
                height = overrideHeight;
            }
            onLoadFailed(new GlideException("Received null model"), logLevel);
            return;
        }
    
        if (status == Status.RUNNING) {
            throw new IllegalArgumentException("Cannot restart a running request");
        }
        //回调target,资源请求已经完成,比如内存缓存,这些不需要再请求网络的
        if (status == Status.COMPLETE) {
            onResourceReady(resource, DataSource.MEMORY_CACHE);
            return;
        }
    
        /**
         *
         *重新启动既没有完成也还没不运行的请求,这些可以被视为新的请求,并且可以从头开始重新运行。
         */
        status = Status.WAITING_FOR_SIZE;
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
            //这里面真的是要请求网络了
            onSizeReady(overrideWidth, overrideHeight);
        } else {
            target.getSize(this);
        }
    
        /**
         * 回调给target通知请求已经开始
         *
         */
        if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE) && canNotifyStatusChanged()) {
            target.onLoadStarted(getPlaceholderDrawable());
        }
    }
    

    直接看我代码的注释吧,其实reSizeReady根据计算大小,然后开始加载图片。

     @Override
    public synchronized void onSizeReady(int width, int height) {
        if (status != Status.WAITING_FOR_SIZE) {
            return;
        }
    
        // 状态表示为运行状态
        status = Status.RUNNING;
    
        float sizeMultiplier = requestOptions.getSizeMultiplier();
        this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
        this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
    
        loadStatus =
                engine.load(
                        glideContext,
                        model,
                        requestOptions.getSignature(),
                        this.width,
                        this.height,
                        requestOptions.getResourceClass(),
                        transcodeClass,
                        priority,
                        requestOptions.getDiskCacheStrategy(),
                        requestOptions.getTransformations(),
                        requestOptions.isTransformationRequired(),
                        requestOptions.isScaleOnlyOrNoTransform(),
                        requestOptions.getOptions(),
                        requestOptions.isMemoryCacheable(),
                        requestOptions.getUseUnlimitedSourceGeneratorsPool(),
                        requestOptions.getUseAnimationPool(),
                        requestOptions.getOnlyRetrieveFromCache(),
                        this,
                        callbackExecutor);
        if (status != Status.RUNNING) {
            loadStatus = null;
        }
    }
    

    就是计算大小,然后开始加载图片,看一下engine.load()方法吧。

    public synchronized <R> LoadStatus load(
            GlideContext glideContext,
            Object model,
            Key signature,
            int width,
            int height,
            Class<?> resourceClass,
            Class<R> transcodeClass,
            Priority priority,
            DiskCacheStrategy diskCacheStrategy,
            Map<Class<?>, Transformation<?>> transformations,
            boolean isTransformationRequired,
            boolean isScaleOnlyOrNoTransform,
            Options options,
            boolean isMemoryCacheable,
            boolean useUnlimitedSourceExecutorPool,
            boolean useAnimationPool,
            boolean onlyRetrieveFromCache,
            ResourceCallback cb,
            Executor callbackExecutor) {
    
        long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;
    
    
        // -------------开始检测缓存----------------
        EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations, resourceClass, transcodeClass, options);
    
        // 第一级内存缓存
        EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
        if (active != null) {
            // 如果内存中有,就立即返回
            cb.onResourceReady(active, DataSource.MEMORY_CACHE);
            if (VERBOSE_IS_LOGGABLE) {
                logWithTimeAndKey("Loaded resource from active resources", startTime, key);
            }
            return null;
        }
        // 第二级内存缓存
        EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
        if (cached != null) {
            cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
            if (VERBOSE_IS_LOGGABLE) {
                logWithTimeAndKey("Loaded resource from cache", startTime, key);
            }
            return null;
        }
    
        EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
        if (current != null) {
            current.addCallback(cb, callbackExecutor);
            if (VERBOSE_IS_LOGGABLE) {
                logWithTimeAndKey("Added to existing load", startTime, key);
            }
            return new LoadStatus(cb, current);
        }
    
        EngineJob<R> engineJob = engineJobFactory.build(key,
                isMemoryCacheable,
                useUnlimitedSourceExecutorPool,
                useAnimationPool,
                onlyRetrieveFromCache);
    
        DecodeJob<R> decodeJob = decodeJobFactory.build(glideContext,
                model,
                key,
                signature,
                width,
                height,
                resourceClass,
                transcodeClass,
                priority,
                diskCacheStrategy,
                transformations,
                isTransformationRequired,
                isScaleOnlyOrNoTransform,
                onlyRetrieveFromCache,
                options,
                engineJob);
    
        jobs.put(key, engineJob);
    
        engineJob.addCallback(cb, callbackExecutor);
    
        // 开始执行任务
        engineJob.start(decodeJob);
        return new LoadStatus(cb, engineJob);
    }
    

    看代码代码注释,应该差不多,主要是 engineJob.start(decodeJob)启动线程执行任务。

     public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor = decodeJob.willDecodeFromCache()
        ? diskCacheExecutor
        : getActiveSourceExecutor();
    executor.execute(decodeJob);
    

    }

    既然是线程,那必然decodeJob一定是Runnable,直奔DecodeJob的run方法,看看究竟干啥。

    @Override
    public void run() {
        //执行网络
        DataFetcher<?> localFetcher = currentFetcher;
        try {
            if (isCancelled) {
                notifyFailed();
                return;
            }
            runWrapped();
        } catch (CallbackException e) {
            throw e;
        } catch (Throwable t) {
            if (stage != Stage.ENCODE) {
                throwables.add(t);
                notifyFailed();
            }
            if (!isCancelled) {
                throw t;
            }
            throw t;
        } finally {
            /**
             * 我们自定组件时回调cleanup(),如OkHttpStreamFetcher中
             *
             */
            if (localFetcher != null) {
                localFetcher.cleanup();
            }
        }
    }
    

    没看到执行什么操作?看一下runWrapped()方法。

      private void runWrapped() {
        switch (runReason) {
            case INITIALIZE://因为刚初始化,
                stage = getNextStage(Stage.INITIALIZE);
                currentGenerator = getNextGenerator();
                runGenerators();
                break;
            case SWITCH_TO_SOURCE_SERVICE:
                runGenerators();
                break;
            case DECODE_DATA:
                decodeFromRetrievedData();//直接解码,然后返回解码后的数据
                break;
            default:
                throw new IllegalStateException("Unrecognized run reason: " + runReason);
        }
    }
    

    这个方法就相当重要了,其实就是根据当前的状态,生成加载图片资源的代Generator,不信?那就看一下getNextGenerator方法。

     private DataFetcherGenerator getNextGenerator() {
        switch (stage) {
            case RESOURCE_CACHE:
                return new ResourceCacheGenerator(decodeHelper, this);//需要解码被转换之后的缓存
            case DATA_CACHE:
                return new DataCacheGenerator(decodeHelper, this);//需要解码原图缓存
            case SOURCE:
                return new SourceGenerator(decodeHelper, this);//原始数据代,需要加载网络数据
            case FINISHED:
                return null;
            default:
                throw new IllegalStateException("Unrecognized stage: " + stage);
        }
    }
    

    不管你信不信,反正我是信了,那创建这些加载图片资源干啥?回到刚才的runWrapper方法,尽然还有runGenerators方法,看一波。

     private void runGenerators() {
        boolean isStarted = false;
    
        /**
         *
         * 如果getNextGenerator()返回SourceGenerator类,那么需要请求网络了
         * 开始网络请求图片
         */
        while (!isCancelled && currentGenerator != null && !(isStarted = currentGenerator.startNext())) {
            stage = getNextStage(stage);
            currentGenerator = getNextGenerator();
    
            if (stage == Stage.SOURCE) {
                //重新调度startNext()
                reschedule();
                return;
            }
        }
        if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
            notifyFailed();
        }
    }
    

    代码不多,看一下currentGenerator.startNext(),这个方法是启动图片加载代Generator的,是个接口,那我们选SourceGenerator这个吧。

     /**
     * 准备开始拉取网络数据
     *
     * @return
     */
    @Override
    public boolean startNext() {
    
        // 判断是否有数据需要取缓存
        if (dataToCache != null) {
            Object data = dataToCache;
            dataToCache = null;
            cacheData(data);
        }
    
        // 如果上一步创建了资源缓存代,就开始资源缓存代
        if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
            return true;
        }
        sourceCacheGenerator = null;
    
        loadData = null;
        boolean started = false;
        while (!started && hasNextModelLoader()) {
            loadData = helper.getLoadData().get(loadDataListIndex++);
    
            if (loadData != null &&
                    (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
                            || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
                started = true;
    
                /**
                 *  DataFetcher的loadData()方法的回调时机,请看实现类{@link HttpUrlFetcher}
                 *
                 *  还把回调传进去
                 */
                loadData.fetcher.loadData(helper.getPriority(), this);
            }
        }
        return started;
    }
    

    DataFetcherGenerator有三个子类分别做不同的事情,

    • SourceGenerator:
      使用已注册的ModelLoaders和为加载提供的model,从原始源数据生成DataFetcher DataFetchers。 根据磁盘缓存策略,源数据可能首先写入磁盘,然后从缓存文件加载而不是直接返回。

    • ResourceCacheGenerator
      从已转换的资源数据的缓存文件中采样数据生成DataFetchers。

    • DataCacheGenerator
      从原始未修改源数据的缓存文件采样数据生成DataFetchers。

    选SourceGenetator分析:

          loadData.fetcher.loadData(helper.getPriority(), this);
    

    使用已注册的ModelLoaders和load提供的model,从原始源数据生成DataFetchers。 根据磁盘缓存策略,源数据可能首先写入磁盘,然后从缓存文件加载而不是直接返回。

    private volatile ModelLoader.LoadData<?> loadData;
    
    
    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(@NonNull Key sourceKey, @NonNull List<Key> alternateKeys,
                        @NonNull DataFetcher<Data> fetcher) {
            this.sourceKey = Preconditions.checkNotNull(sourceKey);
            this.alternateKeys = Preconditions.checkNotNull(alternateKeys);
            this.fetcher = Preconditions.checkNotNull(fetcher);
        }
    }
    

    实际上是如果我们自定义模块,那么会从DataFetcher和ModelLoader中去做网络请求。自此文章结束。

    相关文章

      网友评论

          本文标题:Glide源码分析执行流程

          本文链接:https://www.haomeiwen.com/subject/ztklnqtx.html