Glide源码流程浅析

 

首先Glide作为一个强大的图片加载框架,已经被android官方使用,所以,明白Glide的加载流程以及原理对加深我们对glide的理解是很重要的。下面我们就来分析下  Glide 执行流程,脑袋里面先有一个对  Glide 源码总体执行流程的认识,借鉴一张艽野尘梦绘制的Glide框架图,让我们对Glide的总体框架有一个初步的了解

在这里插入图片描述

 

  首先我们从这一句入手,先看看Glide的初始化过程,也就是Glide.with(this)这个方法。

Glide.with(this).load("").into(new ImageView(this));

  with

  1 调用with

 Glide.with(Activity);

看下 with 这个源码函数,重载有很多。

    @NonNull
    public static RequestManager with(@NonNull Context context) {
        return getRetriever(context).get(context);
    }

    @NonNull
    public static RequestManager with(@NonNull Activity activity) {
        return getRetriever(activity).get(activity);
    }

    @NonNull
    public static RequestManager with(@NonNull FragmentActivity activity) {
        return getRetriever(activity).get(activity);
    }

    @NonNull
    public static RequestManager with(@NonNull Fragment fragment) {
        return getRetriever(fragment.getActivity()).get(fragment);
    }

    /** @deprecated */
    @Deprecated
    @NonNull
    public static RequestManager with(@NonNull android.app.Fragment fragment) {
        return getRetriever(fragment.getActivity()).get(fragment);
    }

    @NonNull
    public static RequestManager with(@NonNull View view) {
        return getRetriever(view.getContext()).get(view);
    }

其实常用的就 Activity,Fragment, Context 这 3 种形式,下面我们就以 Activity 为主。

2 getRetriever(activity)

    @NonNull
    private static RequestManagerRetriever getRetriever(@Nullable Context context) {
        Preconditions.checkNotNull(context, "You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null (which usually occurs when getActivity() is called before the Fragment is attached or after the Fragment is destroyed).");
        return get(context).getRequestManagerRetriever();
    }
    @NonNull
    public static Glide get(@NonNull Context context) {
        if (glide == null) {
            Class var1 = Glide.class;
            synchronized(Glide.class) {
                if (glide == null) {
                    checkAndInitializeGlide(context);
                }
            }
        }

        return glide;
    }
    private static void checkAndInitializeGlide(@NonNull Context context) {
        if (isInitializing) {
            //这里会抛出初始化异常的信息
        } else {
          	//是否初始化标志
            isInitializing = true;
          	//开始进行初始化
            initializeGlide(context);
            isInitializing = false;
        }
    }
 private static void initializeGlide(@NonNull Context context) {
      //实例化一个 GlideBuilder 在进行初始化
   		//GlideBuilder 默认的一些配置信息
   		initializeGlide(context, new GlideBuilder());
    }

通过调用getRetriever 方法 实例化一个 GlideBuilder 进行初始化信息 。

下面我们来看 initializeGlide(context, new GlideBuilder()) 具体做了些什么

 


    private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
        Context applicationContext = context.getApplicationContext();
        //通过反射找到GeneratedAppGlideModuleImpl 类,如果能找到,就说明自定义了GlideModule
        //那么就需要在合适的地方调用applyOptions、registerComponents 来实现自定义的功能
        GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
        List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
        if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
            // 从AndroidManifest.xml 获取自定义的GlideModule(这是另外一种自定义GlideModule的方式)
            manifestModules = new ManifestParser(applicationContext).parse();
        }
		//如果在注解中指明了要排除的GlideModule,则把GlideModule删除,在GlideModule中 从AndroidManifest.xml 中获取的 
        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;
                }
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
                }
                iterator.remove();
            }
        }
		// 获取工厂,用于创建RequestManager(该工厂用于,如果with()参数传递的是application)
        RequestManagerRetriever.RequestManagerFactory factory =
                annotationGeneratedModule != null
                        ? annotationGeneratedModule.getRequestManagerFactory() : null;
        builder.setRequestManagerFactory(factory);
        //执行用户在 manifest 中配置的 GlideModule 接口中的方法
        for (com.bumptech.glide.module.GlideModule module : manifestModules) {
            module.applyOptions(applicationContext, builder);
        }
        //执行使用注解配置的GlideModule 接口中的方法
        if (annotationGeneratedModule != null) {
            annotationGeneratedModule.applyOptions(applicationContext, builder);
        }
        //1 创建Glide,分析
        Glide glide = builder.build(applicationContext);
        //下面registerComponents 方法的执行,需要传递Registry对象,而该对象是在创建Glide 的时候,被赋值,并设置一系列的参数
        //执行用户在 manifest 中配置的 GlideModule 接口中的registerComponents 方法
        for (com.bumptech.glide.module.GlideModule module : manifestModules) {
            module.registerComponents(applicationContext, glide, glide.registry);
        }
        //执行 使用注解配置的GlideModule 接口中的registerComponents 方法
        if (annotationGeneratedModule != null) {
            annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
        }
        applicationContext.registerComponentCallbacks(glide);
        //向单例赋值
        Glide.glide = glide;
    }

 我们通过注释1 看到通过建造者模式创建了一个 Glide 对象,我们现在来看看内部怎么实现的

Glide build(@NonNull Context context) {
       //创建执行器,用于从数据源获取数据,例如网络请求
        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 池,用于回收LruCache缓存的图片,把图片回收到bitmapPool中,这样下次再创建图片时,可服用该内存,避免连续创建回收内存,造成的内存抖动
        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);
        }
        //创建Engine,真正处理request的类,例如发起网络请求图片,从磁盘读取图片等
        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);
        }
        //代码2 getRetriever() 返回的就是该对象
        RequestManagerRetriever requestManagerRetriever =
                new RequestManagerRetriever(requestManagerFactory);
		//创建Glide
        return new Glide(
                context,
                engine,
                memoryCache,
                bitmapPool,
                arrayPool,
                requestManagerRetriever,
                connectivityMonitorFactory,
                logLevel,
                defaultRequestOptions.lock(),
                defaultTransitionOptions,
                defaultRequestListeners,
                isLoggingRequestOriginsEnabled);
    }

上面代码跟注释我们可知,这里 builder 主要构建线程池、复用池、缓存策略、执行 Engine 。现在我们来到真正创建Glide的地方。

代码五 类Glide.java 
   Glide(
            @NonNull Context context,
            @NonNull Engine engine,
            @NonNull MemoryCache memoryCache,
            @NonNull BitmapPool bitmapPool,
            @NonNull ArrayPool arrayPool,
            @NonNull RequestManagerRetriever requestManagerRetriever,
            @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
            int logLevel,
            @NonNull RequestOptions defaultRequestOptions,
            @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
            @NonNull List<RequestListener<Object>> defaultRequestListeners,
            boolean isLoggingRequestOriginsEnabled) {
        this.engine = engine;
        this.bitmapPool = bitmapPool;
        this.arrayPool = arrayPool;
        this.memoryCache = memoryCache;
        this.requestManagerRetriever = requestManagerRetriever;
        this.connectivityMonitorFactory = connectivityMonitorFactory;

        DecodeFormat decodeFormat = defaultRequestOptions.getOptions().get(Downsampler.DECODE_FORMAT);
        bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);

        final Resources resources = context.getResources();

        registry = new Registry();
        registry.register(new DefaultImageHeaderParser());

          ...省略若干代码,创建需要加入到registry 的类...

        ContentResolver contentResolver = context.getContentResolver();
		//添加各种Encoder(把数据存为File)、ResourceDecoder(把数据从类型A转为类型B)、
		//ModelLoaderFactory(用于创建ModelLoader,它用于将任意复杂的数据模型转换为可由 DataFetcher 获取模型所代表的资源数据的具体数据类型。用来加载资源的。 )
        registry
                .append(ByteBuffer.class, new ByteBufferEncoder())
                ...省略若干代码...
                .append(Drawable.class, Drawable.class, new UnitDrawableDecoder())
                /* Transcoders */
                .register(
                        Bitmap.class,
                        BitmapDrawable.class,
                        new BitmapDrawableTranscoder(resources))
                .register(Bitmap.class, byte[].class, bitmapBytesTranscoder)
                .register(
                        Drawable.class,
                        byte[].class,
                        new DrawableBytesTranscoder(
                                bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder))
                .register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder);
        //该工厂用于生产ImageViewTarget,最终通过ImageViewTarget对象把图片addView到界面上 
        ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
        glideContext =
                new GlideContext(
                        context,
                        arrayPool,
                        registry,
                        imageViewTargetFactory,
                        defaultRequestOptions,
                        defaultTransitionOptions,
                        defaultRequestListeners,
                        engine,
                        isLoggingRequestOriginsEnabled,
                        logLevel);
    }

可以看到,代码主要就是Registry 对象,调用append,register 函数设置一些参数。这些参数,主要作用就是对后面的图片解析、加载

 

分析append方法:

  public <Model, Data> Registry append(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<Model, Data> factory) {
    modelLoaderRegistry.append(modelClass, dataClass, factory);
    return this;
  }

直接调用了ModeLoaderRegistry的append方法:

  public synchronized <Model, Data> void append(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    multiModelLoaderFactory.append(modelClass, dataClass, factory);
    cache.clear();
  }

在ModelLoaderRegistry中封装了了一个MultiModelLoaderFactory,MultiModelLoaderFactory里面有一个List,append进来的都最终放到了这个list中,cache只是为了提高效率缓存。具体看ModelLoaderRegistry和MultiModelLoaderFactory源码,关键方法进行了注释。

Registry的append方法没什么难度,这个是放进去,那么我们怎么取出来了呢?

这个就是Registry的getModelLoaders方法,根据Model类型来获取一个ModelLoader的List。可以看ModelLoaderRegistry的源码

package com.bumptech.glide.load.model;
 
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.util.Pools.Pool;
import com.bumptech.glide.Registry.NoModelLoaderAvailableException;
import com.bumptech.glide.util.Synthetic;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * Maintains an ordered put of {@link ModelLoader}s and the model and data types they handle in
 * order from highest priority to lowest.
 */
// Hides Model throughout.
@SuppressWarnings("TypeParameterHidesVisibleType")
public class ModelLoaderRegistry {
 
  private final MultiModelLoaderFactory multiModelLoaderFactory;
  private final ModelLoaderCache cache = new ModelLoaderCache();
 
  public ModelLoaderRegistry(@NonNull Pool<List<Throwable>> throwableListPool) {
    this(new MultiModelLoaderFactory(throwableListPool));
  }
 
  private ModelLoaderRegistry(@NonNull MultiModelLoaderFactory multiModelLoaderFactory) {
    this.multiModelLoaderFactory = multiModelLoaderFactory;
  }
 
  public synchronized <Model, Data> void append(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    multiModelLoaderFactory.append(modelClass, dataClass, factory);
    cache.clear();
  }
 
  public synchronized <Model, Data> void prepend(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    multiModelLoaderFactory.prepend(modelClass, dataClass, factory);
    cache.clear();
  }
 
  public synchronized <Model, Data> void remove(
      @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass) {
    tearDown(multiModelLoaderFactory.remove(modelClass, dataClass));
    cache.clear();
  }
 
  public synchronized <Model, Data> void replace(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    tearDown(multiModelLoaderFactory.replace(modelClass, dataClass, factory));
    cache.clear();
  }
 
  private <Model, Data> void tearDown(
      @NonNull List<ModelLoaderFactory<? extends Model, ? extends Data>> factories) {
    for (ModelLoaderFactory<? extends Model, ? extends Data> factory : factories) {
      factory.teardown();
    }
  }
 
  // We're allocating in a loop to avoid allocating empty lists that will never have anything added
  // to them.
  @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
  @NonNull
  public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
    List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
    if (modelLoaders.isEmpty()) {
      throw new NoModelLoaderAvailableException(model);
    }
    int size = modelLoaders.size();
    boolean isEmpty = true;
    List<ModelLoader<A, ?>> filteredLoaders = Collections.emptyList();
    /*
     *下面这条注释的意思
     * https://stackoverflow.com/questions/17836373/what-does-noinspection-forloopreplaceablebyforeach-mean
     */
    //noinspection ForLoopReplaceableByForEach to improve perf
    for (int i = 0; i < size; i++) {
      ModelLoader<A, ?> loader = modelLoaders.get(i);
      if (loader.handles(model)) {
        if (isEmpty) {
          //这块做了一个小优化,初始化的时候就指定了大小,避免后期扩展的时候拷贝
          filteredLoaders = new ArrayList<>(size - i);
          isEmpty = false;
        }
        filteredLoaders.add(loader);
      }
    }
    if (filteredLoaders.isEmpty()) {
      throw new NoModelLoaderAvailableException(model, modelLoaders);
    }
    return filteredLoaders;
  }
 
  public synchronized <Model, Data> ModelLoader<Model, Data> build(
      @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass) {
    return multiModelLoaderFactory.build(modelClass, dataClass);
  }
 
  @NonNull
  public synchronized List<Class<?>> getDataClasses(@NonNull Class<?> modelClass) {
    return multiModelLoaderFactory.getDataClasses(modelClass);
  }
 
  @NonNull
  private synchronized <A> List<ModelLoader<A, ?>> getModelLoadersForClass(
      @NonNull Class<A> modelClass) {
    //这块又用到了缓存思想,如果没有新的modelClass添加,cache中的就是需要的
    //如果,不从缓存中取,就需要调用multiModelLoaderFactory的build,这样的化,就可能会实例化多个ModelLoader,开销会很大
    List<ModelLoader<A, ?>> loaders = cache.get(modelClass);
    if (loaders == null) {
      loaders = Collections.unmodifiableList(multiModelLoaderFactory.build(modelClass));
      cache.put(modelClass, loaders);
    }
    return loaders;
  }
 
  @NonNull
  @SuppressWarnings("unchecked")
  private static <A> Class<A> getClass(@NonNull A model) {
    return (Class<A>) model.getClass();
  }
 
  private static class ModelLoaderCache {
    private final Map<Class<?>, Entry<?>> cachedModelLoaders = new HashMap<>();
 
    @Synthetic
    ModelLoaderCache() {}
 
    public void clear() {
      cachedModelLoaders.clear();
    }
 
    public <Model> void put(Class<Model> modelClass, List<ModelLoader<Model, ?>> loaders) {
      Entry<?> previous = cachedModelLoaders.put(modelClass, new Entry<>(loaders));
      if (previous != null) {
        throw new IllegalStateException("Already cached loaders for model: " + modelClass);
      }
    }
 
    @Nullable
    @SuppressWarnings("unchecked")
    public <Model> List<ModelLoader<Model, ?>> get(Class<Model> modelClass) {
      Entry<Model> entry = (Entry<Model>) cachedModelLoaders.get(modelClass);
      return entry == null ? null : entry.loaders;
    }
 
    private static class Entry<Model> {
      @Synthetic final List<ModelLoader<Model, ?>> loaders;
 
      public Entry(List<ModelLoader<Model, ?>> loaders) {
        this.loaders = loaders;
      }
    }
  }
}

MultiModelLoaderFactory是一个很重要的类,首先它存储了所有了modelClass、dataClass和ModelLoaderFactory的信息,在entries List里面。还有两个很重要的重载方法load。

synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass)

根据modelClass类型,把所有entries List中的所有modelClass类型的ModelLoader都通过工厂类ModelLoaderFactory方法build出来,并放到loaders List中返回。

需要说明的是不同的ModelLoaderFactory的build实现是不同的,build方法中传入的MultiModelLoaderFactory对象。

3 RequestManager getRetriever(activity).get(activity);

这里的 get 也有很多重载的函数,我们就看 Activity 参数的重载。

public class RequestManagerRetriever implements Handler.Callback {
  


  @NonNull
  public RequestManager get(@NonNull Context context) {
   if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
     //如果在主线程中并且不为 Application 级别的 Context 执行
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        return get((Activity) context);
      } else if (context instanceof ContextWrapper) {
        //一直到查找 BaseContext
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
		//如果不在主线程中或为 Application 就直接执行
    return getApplicationManager(context);
  }

  @NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
		....
  }

  @NonNull
  public RequestManager get(@NonNull Fragment fragment) {
	....
  }

  //通过 Activity 拿到 RequestManager
  @SuppressWarnings("deprecation")
  @NonNull
  public RequestManager get(@NonNull Activity activity) {
    //判断当前是否在子线程中请求任务
    if (Util.isOnBackgroundThread()) {
      //通过 Application 级别的 Context 加载
      return get(activity.getApplicationContext());
    } else {
      //检查 Activity 是否已经销毁
      assertNotDestroyed(activity);
      //拿到当前 Activity 的 FragmentManager 
      android.app.FragmentManager fm = activity.getFragmentManager();
      //主要是生成一个 Fragment 然后绑定一个请求管理 RequestManager
      return fragmentGet(
          activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }
}

下面我们看下 fragmentGet 函数实现

  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    //1. 在当前的 Acitivty 添加一个 Fragment 用于管理请求的生命周期
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    //拿到当前请求的管理类
    RequestManager requestManager = current.getRequestManager();
    //如果不存在,则创建一个请求管理者保持在当前管理生命周期的 Fragment 中,相当于 2 者进行绑定,避免内存泄漏。
    if (requestManager == null) {
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    //返回当前请求的管理者
    return requestManager;
  }

通过上面的代码可知,这里用于 Fragment 管理请求的生命周期,那么我们具体来看看 Fragment 怎么添加到 Activity 中。

  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    //通过 TAG 拿到已经实例化过的 Fragment ,相当于如果同一个 Activity Glide.with..多次,那么就没有必要创建多个。
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    //如果在当前 Activity 中没有拿到管理请求生命周期的 Fragment ,那么就从缓存中看有没有
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      //如果缓存也没有得,就直接实例化一个 Fragment
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        //如果已经有执行的请求就开始
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        //添加到 Map 缓存中
        pendingRequestManagerFragments.put(fm, current);
        //通过当前 Activity 的 FragmentManager 开始提交添加一个 Fragment 容器
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        //添加到 FragmentManager 成功,发送清理缓存。
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

最后就到了 把请求管理类绑定到 Fragment 中。

  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    ...
    //如果不存在,则创建一个请求管理者保持在当前管理生命周期的 Fragment 中,相当于 2 者进行绑定,避免内存泄漏。
    if (requestManager == null) {
      //拿到单例 Glide
      Glide glide = Glide.get(context);
      //构建请求管理,current.getGlideLifecycle(),就是 ActivityFragmentLifecycle 后面我们会讲到这个类
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      //将构建出来的请求管理绑定在 Fragment 中。
      current.setRequestManager(requestManager);
    }
    //返回当前请求的管理者
    return requestManager;
  }

看下怎么构建请求管理类的

  private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
    @NonNull
    @Override
    public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
      //实例化
      return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
    }
  };
public RequestManager(
      @NonNull Glide glide, @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
    this(
        glide,
        lifecycle,
        treeNode,
        new RequestTracker(),
        glide.getConnectivityMonitorFactory(),
        context);
  }

  // Our usage is safe here.
  @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.context = context;

    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

    //这里只要是添加生命周期监听,Fragment 传递过来的
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    //添加网络变化的监听
    lifecycle.addListener(connectivityMonitor);

    defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
		
    glide.registerRequestManager(this);
  }

到这里请求管理类 RequestManager + Fragment 已经绑定成功了,声明周期监听也设置了。

那他们相互是怎么保证生命周期的传递勒,我们主要看 Fragment 生命周期方法

//这里为什么监控 Fragment 的生命周期勒,其实大家应该也知道 Fragment 是依附在 Activity 的 Activity 的生命周期在 Fragment 中都有,所以监听 Fragment 就行了。
public class RequestManagerFragment extends Fragment {
  
  //相当于生命周期回调
	private final ActivityFragmentLifecycle lifecycle;
  
  ....


  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }

  @Override
  public void onStop() {
    super.onStop();
    lifecycle.onStop();
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    lifecycle.onDestroy();
  }
  
  ...
}

这里的 lifecycle 负责生命周期的处理,我们在深入看看去

class ActivityFragmentLifecycle implements Lifecycle {
  private final Set<LifecycleListener> lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
  private boolean isStarted;
  private boolean isDestroyed;


  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.add(listener);

    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.remove(listener);
  }

  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }

  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }
}

这里知道了吧,它实现的是 Glide 中的 Lifecycle 生命周期接口,注册是在刚刚我们讲解 RequestManagerFactory 工厂中实例化的 RequestManager 然后在构造函数中添加了生命周期回调监听,具体来看下。

public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
      
      ...
         @Override
  public synchronized void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }


  @Override
  public synchronized void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }


  @Override
  public synchronized void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }
        
     	...
    }

二 load

load 函数加载相对于比较简单。我们看下具体代码实现

public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
      
  .....
    
  public RequestBuilder<Drawable> load(@Nullable String string) {
    //这里调用 Drawable 图片加载请求器为其加载
    return asDrawable().load(string);
  }
  
  public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
  }

  @NonNull
  @CheckResult
  @Override
  public RequestBuilder<Drawable> load(@Nullable Uri uri) {
    return asDrawable().load(uri);
  }


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

可以看到 load 也有很多重载的函数,不得不说是真的很强大啊,只要给一个图片资源那么就能给你加载出来。

public class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>>
    implements Cloneable, ModelTypes<RequestBuilder<TranscodeType>> {
        
  public RequestBuilder<TranscodeType> load(@Nullable String string) {
    return loadGeneric(string);
  }
  
  // 描述加载的数据源-这里可以看做是我们刚刚传递进来的 http://xxxx.png
  @Nullable private Object model;
  // 描述这个请求是否已经添加了加载的数据源
  private boolean isModelSet;
  
  private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }
}

好的, 到这里 RequestBuilder 就构建好了, 接下来就等待执行这个请求了, 我们看看它的 RequestBuilder 的 into 方法。

 

三 into

public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    Util.assertMainThread();
    Preconditions.checkNotNull(view);

    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {
   //根据ImageView 的ScaleType 类型,进行参数设置,注意这里是clone 一个新的对象,在新对象上操作的
     
      switch (view.getScaleType()) {
        case CENTER_CROP:
          requestOptions = requestOptions.clone().optionalCenterCrop();
          break;
        case CENTER_INSIDE:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case FIT_CENTER:
        case FIT_START:
        case FIT_END:
          requestOptions = requestOptions.clone().optionalFitCenter();
          break;
        case FIT_XY:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case CENTER:
        case MATRIX:
        default:
          // Do nothing.
      }
    }
           1
    return into(
        
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
  }
 public <X> ViewTarget<ImageView, X> buildImageViewTarget(
      @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
    return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
  }
  public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
      @NonNull Class<Z> clazz) {
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      //因为前面调用asDrawable ,所以会创建这个ViewTarget
      return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
  }

  如上步骤通过 ImageViewTargetFactory  创建 BitmapImageViewTarget 和DrawableImageViewTarget 。

   先拿到当前 ImageView getScaleType 类型的属性,然后重新 clone 一个进行配置;调用 into 重载继续构建

  回到1 处 

    private <Y extends Target<TranscodeType>> Y into(
            @NonNull Y target,
            @Nullable RequestListener<TranscodeType> targetListener,
            BaseRequestOptions<?> options,
            Executor callbackExecutor) {
        Preconditions.checkNotNull(target);
        if (!isModelSet) {
            //调用过load 函数,这个变量是true
            throw new IllegalArgumentException("You must call #load() before calling #into()");
        }
		//创建请求,用于显示图片。图片有可能是从缓存中,也有可能是从网络获取
        Request request = buildRequest(target, targetListener, options, callbackExecutor);
        
		//获取该目标 对应的request,和当前的request进行比较
        Request previous = target.getRequest();
        if (request.isEquivalentTo(previous)
                && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
            request.recycle();
            // If the request is completed, beginning again will ensure the result is re-delivered,
            // triggering RequestListeners and Targets. If the request is failed, beginning again will
            // restart the request, giving it another chance to complete. If the request is already
            // running, we can let it continue running without interruption.
            if (!Preconditions.checkNotNull(previous).isRunning()) {
                // Use the previous request rather than the new one to allow for optimizations like skipping
                // setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
                // that are done in the individual Request.
                previous.begin();
            }
            return target;
        }

        requestManager.clear(target);
        //把当前的request,设置到target(ViewTarget)
        target.setRequest(request);
        //2 进行图片请求操作 
        requestManager.track(target, request);

        return target;
    }
  1. 为 target buildRequest 构建一个 Glide request 请求;
  2. 将构建出来的 Request 交于 RequestManager 来执行.

现在看 request 创建出来的操作 

private Request buildRequest(
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {
    return buildRequestRecursive(
        target,
        targetListener,
        /*parentCoordinator=*/ null,
        transitionOptions,
        requestOptions.getPriority(),
        requestOptions.getOverrideWidth(),
        requestOptions.getOverrideHeight(),
        requestOptions,
        callbackExecutor);
  }

  private Request buildRequestRecursive(
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor) {

    // Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
    ErrorRequestCoordinator errorRequestCoordinator = null;
    if (errorBuilder != null) {
      errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
      parentCoordinator = errorRequestCoordinator;
    }

    Request mainRequest =
        buildThumbnailRequestRecursive(
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);

    if (errorRequestCoordinator == null) {
      return mainRequest;
    }

    int errorOverrideWidth = errorBuilder.getOverrideWidth();
    int errorOverrideHeight = errorBuilder.getOverrideHeight();
    if (Util.isValidDimensions(overrideWidth, overrideHeight)
        && !errorBuilder.isValidOverride()) {
      errorOverrideWidth = requestOptions.getOverrideWidth();
      errorOverrideHeight = requestOptions.getOverrideHeight();
    }

    Request errorRequest =
        errorBuilder.buildRequestRecursive(
            target,
            targetListener,
            errorRequestCoordinator,
            errorBuilder.transitionOptions,
            errorBuilder.getPriority(),
            errorOverrideWidth,
            errorOverrideHeight,
            errorBuilder,
            callbackExecutor);
    errorRequestCoordinator.setRequests(mainRequest, errorRequest);
    return errorRequestCoordinator;
  }

 

    private Request buildThumbnailRequestRecursive(
            Target<TranscodeType> target,
            RequestListener<TranscodeType> targetListener,
            @Nullable RequestCoordinator parentCoordinator,
            TransitionOptions<?, ? super TranscodeType> transitionOptions,
            Priority priority,
            int overrideWidth,
            int overrideHeight,
            BaseRequestOptions<?> requestOptions,
            Executor callbackExecutor) {
        if (thumbnailBuilder != null) {
            // Recursive case: contains a potentially recursive thumbnail request builder.
            TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
                    thumbnailBuilder.transitionOptions;

            // Apply our transition by default to thumbnail requests but avoid overriding custom options
            // that may have been applied on the thumbnail request explicitly.
            if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
                thumbTransitionOptions = transitionOptions;
            }
			//取出缩略图的配置,优先级,,缩略图的宽高等
            Priority thumbPriority = thumbnailBuilder.isPrioritySet()
                    ? thumbnailBuilder.getPriority() : getThumbnailPriority(priority);

            int thumbOverrideWidth = thumbnailBuilder.getOverrideWidth();
            int thumbOverrideHeight = thumbnailBuilder.getOverrideHeight();
            if (Util.isValidDimensions(overrideWidth, overrideHeight)
                    && !thumbnailBuilder.isValidOverride()) {
                thumbOverrideWidth = requestOptions.getOverrideWidth();
                thumbOverrideHeight = requestOptions.getOverrideHeight();
            }

            ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
            //使用缩略图的参数,创建一个Request
            Request fullRequest =
                    obtainRequest(
                            target,
                            targetListener,
                            requestOptions,
                            coordinator,
                            transitionOptions,
                            priority,
                            overrideWidth,
                            overrideHeight,
                            callbackExecutor);
            isThumbnailBuilt = true;
            // Recursively generate thumbnail requests.
            //因为调用.thumbnail 传递GlideRequest 参数时,这个请求也可能设置了缩略图和错误图(也就是缩略图的缩略图),所以这里进行递归创建Request
            Request thumbRequest =
                    thumbnailBuilder.buildRequestRecursive(
                            target,
                            targetListener,
                            coordinator,
                            thumbTransitionOptions,
                            thumbPriority,
                            thumbOverrideWidth,
                            thumbOverrideHeight,
                            thumbnailBuilder,
                            callbackExecutor);
            isThumbnailBuilt = false;
            coordinator.setRequests(fullRequest, thumbRequest);
            return coordinator;
        } 

         ... 下面省略若干代码,是根据其他情况,创建Request ...
    }

继续跟踪

  private Request obtainRequest(
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      RequestCoordinator requestCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      Executor callbackExecutor) {
    return SingleRequest.obtain(
        context,
        glideContext,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(),
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
  }

最后我们发现是 SingleRequest.obtain 来为我们构建的 Request 请求对象,开始只是初始化一些配置属性,下面我们就来找最开始 标注2的地方, 先来看下 track 函数执行。

//这里对当前 class 加了一个同步锁避免线程引起的安全性  
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
  	//添加一个目标任务  
  	targetTracker.track(target);
  	//执行 Glide request
    requestTracker.runRequest(request);
  }
  public void runRequest(@NonNull Request request) {
    //添加一个请求
    requests.add(request);
    //是否暂停
    if (!isPaused) {
      //没有暂停,开始调用 Request begin 执行
      request.begin();
    } else {
      //如果调用了 暂停,清理请求
      request.clear();
      pendingRequests.add(request);
    }
  }

上面的逻辑是先为 requests 添加一个请求,看看是否是停止状态,如果不是就调用 request.begin();执行。

这里的 Request 是一个接口,通过之前我们讲到 buildRequest 函数可知  Request 的实现类是  SingleRequest 我们就直接看它的 begin 函数.

    public synchronized void begin() {
        ...
        if (model == null) {

            ...
            // model(url)为空,回调加载失败
           onLoadFailed(new GlideException("Received null   model"), logLevel);
           return;
        }
        if (status == Status.RUNNING) {
            throw new IllegalArgumentException("Cannot restart a running request");
        }

        // If we're restarted after we're complete (usually via something like a notifyDataSetChanged
        // that starts an identical request into the same Target or View), we can simply use the
        // resource and size we retrieved the last time around and skip obtaining a new size, starting a
        // new load etc. This does mean that users who want to restart a load because they expect that
        // the view size has changed will need to explicitly clear the View or Target before starting
        // the new load.
        if (status == Status.COMPLETE) {
            
            onResourceReady(resource, DataSource.MEMORY_CACHE);
            return;
        }

        // Restarts for requests that are neither complete nor running can be treated as new requests
        // and can run again from the beginning.

        status = Status.WAITING_FOR_SIZE;
        //glide 会根据显示图片的宽高进行缓存,所以这里需要获得View的宽高,overrideWidth,overrideHeight默认为-1
        //所以第一次会到else分支,获取View的宽高
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
            // 当使用override() API为图片指定了一个固定的宽高时直接执行onSizeReady,
            // 最终的核心处理位于onSizeReady
            onSizeReady(overrideWidth, overrideHeight);
        } else {
            // 根据imageView的宽高算出图片的宽高,最终也会走到onSizeReady
            target.getSize(this);
        }

        if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
                && canNotifyStatusChanged()) {
             // 预先加载设置的缩略图
            target.onLoadStarted(getPlaceholderDrawable());
        }
    }

我们接着往下看 onSizeReady

    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);
		
		//这里的engine 是在创建Glide的时候,build() 创建的,engine封装了各种Executor,内存缓存等
        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);

        // This is a hack that's only useful for testing right now where loads complete synchronously
        // even though under any executor running on any thread but the main thread, the load would
        // have completed asynchronously.
        if (status != Status.RUNNING) {
            loadStatus = null;
        }
    }

接着再看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) {

    //拿到缓存或者请求的 key
    EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
        resourceClass, transcodeClass, options);
		//根据 key 拿到活动缓存中的资源
    EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
    //如果 ActiveResources 活动缓存中有就回调出去
    if (active != null) {
      cb.onResourceReady(active, DataSource.MEMORY_CACHE);
      return null;
    }

    //尝试从 LruResourceCache 中找寻这个资源 
    EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
    if (cached != null) {
      //如果内存缓存 Lru 中资源存在回调出去
      cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
      return null;
    }

    //------------- 走到这里说明活动缓存 跟内存 缓存都没有找到 -----------
    
    //根据 Key 看看缓存中是否正在执行
    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);
		//把当前需要执行的 key 添加进缓存
    jobs.put(key, engineJob);
		//执行任务的回调
    engineJob.addCallback(cb, callbackExecutor);
    //开始执行。
    engineJob.start(decodeJob);

    return new LoadStatus(cb, engineJob);
  }

通过 engine.load 这个函数里面的逻辑,我们可以总结几点:

  1. 先构建请求或者缓存 KEY ;
  2. 根据 KEY 从内存缓存中查找对应的资源数据(ActiveResources(活动缓存,内部是一个 Map 用弱引用持有),LruResourceCache),如果有就回调 对应监听的 onResourceReady 表示数据准备好了。
  3. 从执行缓存中查找对应 key 的任务
    1. 如果找到了,就说明已经正在执行了,不用重复执行。
    2. 没有找到,通过 EngineJob.start 开启一个新的请求任务执行。

接着往下看

engine .start 

  public synchronized void start(DecodeJob<R> decodeJob) {
        this.decodeJob = decodeJob;
        //若能从磁盘缓存获取数据,就使用diskCacheExecutor
        //否则在根据其他的条件判断使用哪个Executor
        GlideExecutor executor = decodeJob.willDecodeFromCache()
                ? diskCacheExecutor
                : getActiveSourceExecutor();
        executor.execute(decodeJob);
    }

   boolean willDecodeFromCache() {
        //先看下面的getNextStage 分析
        Stage firstStage = getNextStage(Stage.INITIALIZE);
        //那这里就很明了了,如果可以从磁盘缓存读取,就返回true
        return firstStage == Stage.RESOURCE_CACHE || firstStage == Stage.DATA_CACHE;
    }

接着往下看 get NextState 获取下一个阶段,应该从哪里获取数据

    private Stage getNextStage(Stage current) {
        switch (current) {
            case INITIALIZE:
            //当前是初始阶段,则看磁盘缓存策略,是否可以在磁盘中获取资源缓存(也就是解析后的缓存)
                return diskCacheStrategy.decodeCachedResource()
                        ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
            case RESOURCE_CACHE:
            //当前是资源缓存,看下一步能不能从磁盘缓存中获取源数据缓存
                return diskCacheStrategy.decodeCachedData()
                        ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
            case DATA_CACHE:
                // Skip loading from source if the user opted to only retrieve the resource from cache.
                //当前是数据缓存,下一步能不能从源数据处获取数据,例如从服务器获取
                return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
            case SOURCE:
            case FINISHED:
                return Stage.FINISHED;
            default:
                throw new IllegalArgumentException("Unrecognized stage: " + current);
        }
    }

下面我们就来看下 engineJob.start 具体执行逻辑:

  public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    //拿到 Glide 执行的线程池
    GlideExecutor executor = decodeJob.willDecodeFromCache()
        ? diskCacheExecutor
        : getActiveSourceExecutor();
    //开始执行
    executor.execute(decodeJob);
  }

 我们这里看到 GlideExecutor 线程池 实现run 的方法

class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable<DecodeJob<?>>,
    Poolable {
      
  //线程执行调用 run
@Override
  public void run() {

    GlideTrace.beginSectionFormat("DecodeJob#run(model=%s)", model);
   
    DataFetcher<?> localFetcher = currentFetcher;
    try {
      //是否取消了当前请求
      if (isCancelled) {
        notifyFailed();
        return;
      }
      //执行
      runWrapped();
    } catch (CallbackException e) {
      
      
     .....//一些错误回调
  }
    }

  接着看  runWrapped 

    /**
     * 初始化之后第一次运行时 runReason 为 INITIALIZE
     */
    private void runWrapped() {
        runWrappedCount++;
        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);
        }
    }

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

    private void runGenerators() {
        currentThread = Thread.currentThread();
        startFetchTime = LogTime.getLogTime();
        boolean isStarted = false;
        while (!isCancelled && currentGenerator != null
                   //这里执行当前的Generator,进第11步
                && !(isStarted = currentGenerator.startNext())) {

            stage = getNextStage(stage);
            currentGenerator = getNextGenerator();

            if (stage == Stage.SOURCE) {
                reschedule();
                return;
            }
        }
        // We've run out of stages and generators, give up.
        if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
            notifyFailed();
        }

        // Otherwise a generator started a new load and we expect to be called back in
        // onDataFetcherReady.
    }

currentGenerator.startNext() 这里的currentGenerator 是SourceGenerator

接着 往下看。SourceGenerator  startNext

    @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()) {
            //helper.getLoadData() 获取所有符合条件的ModelLoader,这些ModelLoader 包括默认的和自定义的
           // 这里的符合条件,也就是ModelLoader 中的handles函数是否返回true,再说直白点,就是判断在load()传入的对象类型,是否可以被ModelLoader所处理
            loadData = helper.getLoadData().get(loadDataListIndex++);
            if (loadData != null
                    && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
                    || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
                started = true;
                //3 通过LoadData对象内部的 fetcher ,来进行实际的请求操作(例如发起网络请求)
                loadData.fetcher.loadData(helper.getPriority(), this);
            }
        }
        return started;
    }
    List<LoadData<?>> getLoadData() {
        if (!isLoadDataSet) {
            isLoadDataSet = true;
            loadData.clear();
            //获取已注册的加载器中所有可以加载当前模型的加载器
            List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
            //noinspection ForLoopReplaceableByForEach to improve perf
            for (int i = 0, size = modelLoaders.size(); i < size; i++) {
                ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
                //每一个ModeLoader 都有一个内部类LoadData,通过函数buildLoadData 来创建
                LoadData<?> current =
                        modelLoader.buildLoadData(model, width, height, options);
                if (current != null) {
                    loadData.add(current);
                }
            }
        }
        return loadData;
    }

现在接着看 glideContext.getRegistry().getModelLoaders(model);   这里通过getRegistry() 得到 Registry。 接着下来看如何获取LoadData。

查看 Registry 中的方法 getModelLoaders

@NonNull
    public <Model> List<ModelLoader<Model, ?>> getModelLoaders(@NonNull Model model) {
        List<ModelLoader<Model, ?>> result = modelLoaderRegistry.getModelLoaders(model);
        if (result.isEmpty()) {
            throw new NoModelLoaderAvailableException(model);
        }
        return result;
    }
    public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
        List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
        int size = modelLoaders.size();
        boolean isEmpty = true;
        List<ModelLoader<A, ?>> filteredLoaders = Collections.emptyList();
        for (int i = 0; i < size; i++) {
            ModelLoader<A, ?> loader = modelLoaders.get(i);
            //通过 ModelLoader#handles 方法判断加载器是否可以处理当前类型的数据(这个数据时通过load 传递进来的),返回所有可以处理的加载器
            if (loader.handles(model)) {
                if (isEmpty) {
                    filteredLoaders = new ArrayList<>(size - i);
                    isEmpty = false;
                }
                filteredLoaders.add(loader);
            }
        }
        return filteredLoaders;
    }

这里的 modelLoader 有一个类型是StringLoader ,StringLoader.buildLoadData->MultiModelLoader.buildLoadData

  @Override
  public LoadData<Data> buildLoadData(
      @NonNull Model model, int width, int height, @NonNull Options options) {
    Key sourceKey = null;
    int size = modelLoaders.size();
    List<DataFetcher<Data>> fetchers = new ArrayList<>(size);
    //noinspection ForLoopReplaceableByForEach to improve perf
    for (int i = 0; i < size; i++) {
      //这里的modelLoaders,是在创建MultiModelLoader的时候赋值的
      ModelLoader<Model, Data> modelLoader = modelLoaders.get(i);
      //在这里有进行了一次过滤,在更小的范围内查找,可以处理model的ModelLoader。(这次是在StringLoader 中查找,可以处理URL的ModelLoader)
      if (modelLoader.handles(model)) {
        LoadData<Data> loadData = modelLoader.buildLoadData(model, width, height, options);
        if (loadData != null) {
          //这里把LoadData的值提取出来,
          sourceKey = loadData.sourceKey;
          //以本例子,这里的fetcher 是HttpUrlFetcher 
          fetchers.add(loadData.fetcher);
        }
      }
    }
    return !fetchers.isEmpty() && sourceKey != null
        ? new LoadData<>(sourceKey, new MultiFetcher<>(fetchers, exceptionListPool))
        : null;
  }

获取LoadData后  回到startNext ,标注3位置,来到loadData.fetcher.loadData(helper.getPriority(), this); 这里的fetcher 是 HttpUrlFetcher ,我们现在来看 loadData的实现

  @Override
  public void loadData(@NonNull Priority priority,
      @NonNull DataCallback<? super InputStream> callback) {
    long startTime = LogTime.getLogTime();
    try {
      //http 请求,返回一个 InputStream 输入流
      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
      //将 InputStream 以回调形式回调出去
      callback.onDataReady(result);
    } catch (IOException e) {
      callback.onLoadFailed(e);
    } finally {
     ...
    }
  }

我们继续看 loadDataWithRedirects 这个函数是怎么生成的一个 InputStream

  private InputStream loadDataWithRedirects(URL url, int redirects, URL lastUrl,
      Map<String, String> headers) throws IOException {
    if (redirects >= MAXIMUM_REDIRECTS) {
      throw new HttpException("Too many (> " + MAXIMUM_REDIRECTS + ") redirects!");
    } else {

      try {
        if (lastUrl != null && url.toURI().equals(lastUrl.toURI())) {
          throw new HttpException("In re-direct loop");
        }
      } catch (URISyntaxException e) {
        // Do nothing, this is best effort.
      }
    }

    urlConnection = connectionFactory.build(url);
    for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
      urlConnection.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
    }
    urlConnection.setConnectTimeout(timeout);
    urlConnection.setReadTimeout(timeout);
    urlConnection.setUseCaches(false);
    urlConnection.setDoInput(true);

    urlConnection.setInstanceFollowRedirects(false);


    urlConnection.connect();

    stream = urlConnection.getInputStream();
    if (isCancelled) {
      return null;
    }
    final int statusCode = urlConnection.getResponseCode();
    if (isHttpOk(statusCode)) {
      return getStreamForSuccessfulRequest(urlConnection);
    } 
    ...//抛的异常我们暂时先不管
  }

现在看到Http 请求了,这里是 HttpURLConnection 作为 Glide 底层成网络请求的。请求成功之后直接返回的是一个输入流,最后会通过 onDataReady 回调到 DecodeJob onDataFetcherReady 函数,我们跟下回掉回到 SourceGenerator 中

    @Override
    public void onDataReady(Object data) {

        DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
        if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
          
            dataToCache = data;
            //调用DecodeJob的reschedule,用线程池执行任务,实际上就是再次调用SourceGenerator的startNext
            cb.reschedule();
        } else {
          // 又是一个回调函数
            cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher,
                    loadData.fetcher.getDataSource(), originalKey);
        }
    }

这里会有 else 因为我们没有配置缓存,继续回调。

 

class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
    Runnable,
    Comparable<DecodeJob<?>>,
    Poolable {
      ...
         @Override
  public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
      DataSource dataSource, Key attemptedKey) {
    this.currentSourceKey = sourceKey; //当前返回数据的 key
    this.currentData = data; //返回的数据
    this.currentFetcher = fetcher; //返回的数据执行器,这里可以理解为 HttpUrlFetcher
    this.currentDataSource = dataSource; //数据来源 url
    this.currentAttemptingKey = attemptedKey;
    if (Thread.currentThread() != currentThread) {
      runReason = RunReason.DECODE_DATA;
      callback.reschedule(this);
    } else {
      GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
      try {
        //4 解析返回回来的数据
        decodeFromRetrievedData();
      } finally {
        GlideTrace.endSection();
      }
    }
  }   
      ...
      
    }


	//解析返回的数据
  private void decodeFromRetrievedData() {
    Resource<R> resource = null;
    try {
      // 调用 decodeFrom 解析 数据;HttpUrlFetcher , InputStream ,  currentDataSource
      resource = decodeFromData(currentFetcher, currentData, currentDataSource);
    } catch (GlideException e) {
      e.setLoggingDetails(currentAttemptingKey, currentDataSource);
      throwables.add(e);
    }
    //解析完成后,通知下去
    if (resource != null) {
      notifyEncodeAndRelease(resource, currentDataSource);
    } else {
      runGenerators();
    }
  }

续跟 decodeFromData 看看怎么解析成 Resource 的

 

    private <Data> Resource<R> decodeFromData(DataFetcher<?> fetcher, Data data,
                                              DataSource dataSource) throws GlideException {

        try {
            if (data == null) {
                return null;
            }
            //继续解析数据
            Resource<R> result = decodeFromFetcher(data, dataSource);
            return result;
        } finally {
            fetcher.cleanup();
        }
    }
    //这里的data 是一个泛型,本例中是 Stream 流,从http请求获取到的
    private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
            throws GlideException {
        //获取一个LoadPath,它是根据数据类型(这里是stream),ResourceDecoder(资源解码),transcoder(资源转码)
        //从这些参数可以看出,最终把数据流转为Bitmap 或Drawable ,就是在LoadPath中进行的,这里是指DecodePath
        LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
        return runLoadPath(data, dataSource, path);
    }
    private <Data, ResourceType> Resource<R> runLoadPath(Data data, DataSource dataSource,
                                                         LoadPath<Data, ResourceType, R> path) throws GlideException {
        Options options = getOptionsWithHardwareConfig(dataSource);
        DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
        try {
            // ResourceType in DecodeCallback below is required for compilation to work with gradle.
            //执行LoadPath 的load ,进行解码,转换操作
            return path.load(
                    rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
        } finally {
            rewinder.cleanup();
        }
    }

上面代码看到,为了解析数据首先构建一个 LoadPath, 然后创建一个 InputStreamRewinder 类型的 DataRewinder, 最终将数据解析的操作放到了 LoadPath.load 方法中 ,接下来看下 LoadPath.load 方法的具体逻辑操作:

    public Resource<Transcode> load(DataRewinder<Data> rewinder, @NonNull Options options, int width,
                                    int height, DecodePath.DecodeCallback<ResourceType> decodeCallback) throws GlideException {
        
        try {
            return loadWithExceptionList(rewinder, options, width, height, decodeCallback, throwables);
        } 
    }

    private Resource<Transcode> loadWithExceptionList(DataRewinder<Data> rewinder,
                                                      @NonNull Options options,
                                                      int width, int height, DecodePath.DecodeCallback<ResourceType> decodeCallback,
                                                      List<Throwable> exceptions) throws GlideException {
        Resource<Transcode> result = null;
        //noinspection ForLoopReplaceableByForEach to improve perf
        for (int i = 0, size = decodePaths.size(); i < size; i++) {
            DecodePath<Data, ResourceType, Transcode> path = decodePaths.get(i);
            try {
                //重点在这里,调用LoadPath 的decode 解码
                result = path.decode(rewinder, width, height, options, decodeCallback);
            } catch (GlideException e) {
                exceptions.add(e);
            }
            if (result != null) {
                break;
            }
        }

        if (result == null) {
            throw new GlideException(failureMessage, new ArrayList<>(exceptions));
        }

        return result;
    }

跟 path.decode

  public Resource<Transcode> decode(DataRewinder<DataType> rewinder, int width, int height,
      @NonNull Options options, DecodeCallback<ResourceType> callback) throws GlideException {
    //调用 decodeResourec 将数据解析成中间资源
    Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options);
    //解析完数据回调出去
    Resource<ResourceType> transformed = callback.onResourceDecoded(decoded);
    //转换资源为目标资源
    return transcoder.transcode(transformed, options);
  }
  @NonNull
  private Resource<ResourceType> decodeResource(DataRewinder<DataType> rewinder, int width,
      int height, @NonNull Options options) throws GlideException {
   ...
    try {
      return decodeResourceWithList(rewinder, width, height, options, exceptions);
    } finally {
    ...
    }
  }

  @NonNull
  private Resource<ResourceType> decodeResourceWithList(DataRewinder<DataType> rewinder, int width,
      int height, @NonNull Options options, List<Throwable> exceptions) throws GlideException {
    Resource<ResourceType> result = null;
    //noinspection ForLoopReplaceableByForEach to improve perf
    for (int i = 0, size = decoders.size(); i < size; i++) {
      ResourceDecoder<DataType, ResourceType> decoder = decoders.get(i);
      try {
        DataType data = rewinder.rewindAndGet();
        if (decoder.handles(data, options)) {
          data = rewinder.rewindAndGet();
          // 调用 ResourceDecoder.decode 解析数据
          result = decoder.decode(data, width, height, options);
        }

      } catch (IOException | RuntimeException | OutOfMemoryError e) {
				...
      }

    return result;
  }

decode是一个ResourceDecoder接口(资源解码器),根据不同的DataType和ResourceType它会有不同的实现类,这里的实现类是ByteBufferBitmapDecoder,下面看看它的decode 流程

  public Resource<Bitmap> decode(@NonNull ByteBuffer source, int width, int height,
      @NonNull Options options)
      throws IOException {
    InputStream is = ByteBufferUtil.toStream(source);
    return downsampler.decode(is, width, height, options);
  }

downsampler主要是对流进行解码,旋转,压缩,圆角等处理 ,

    public Resource<Bitmap> decode(InputStream is, int requestedWidth, int requestedHeight,
                                   Options options, DecodeCallbacks callbacks) throws IOException {


        byte[] bytesForOptions = byteArrayPool.get(ArrayPool.STANDARD_BUFFER_SIZE_BYTES, byte[].class);
        BitmapFactory.Options bitmapFactoryOptions = getDefaultOptions();
        bitmapFactoryOptions.inTempStorage = bytesForOptions;

        DecodeFormat decodeFormat = options.get(DECODE_FORMAT);
        DownsampleStrategy downsampleStrategy = options.get(DownsampleStrategy.OPTION);
        boolean fixBitmapToRequestedDimensions = options.get(FIX_BITMAP_SIZE_TO_REQUESTED_DIMENSIONS);
        boolean isHardwareConfigAllowed =
                options.get(ALLOW_HARDWARE_CONFIG) != null && options.get(ALLOW_HARDWARE_CONFIG);

        try {
            //解析得到bitmap
            Bitmap result = decodeFromWrappedStreams(is, bitmapFactoryOptions,
                    downsampleStrategy, decodeFormat, isHardwareConfigAllowed, requestedWidth,
                    requestedHeight, fixBitmapToRequestedDimensions, callbacks);
             //把bitmap 封装进Resource ,返回Resource 对象
            return BitmapResource.obtain(result, bitmapPool);
        } finally {
            releaseOptions(bitmapFactoryOptions);
            byteArrayPool.put(bytesForOptions);
        }
    }
  private Bitmap decodeFromWrappedStreams(
      ImageReader imageReader,
      BitmapFactory.Options options,
      DownsampleStrategy downsampleStrategy,
      DecodeFormat decodeFormat,
      PreferredColorSpace preferredColorSpace,
      boolean isHardwareConfigAllowed,
      int requestedWidth,
      int requestedHeight,
      boolean fixBitmapToRequestedDimensions,
      DecodeCallbacks callbacks)
      throws IOException {
    long startTime = LogTime.getLogTime();

    int[] sourceDimensions = getDimensions(imageReader, options, callbacks, bitmapPool);
    int sourceWidth = sourceDimensions[0];
    int sourceHeight = sourceDimensions[1];
    String sourceMimeType = options.outMimeType;

    // If we failed to obtain the image dimensions, we may end up with an incorrectly sized Bitmap,
    // so we want to use a mutable Bitmap type. One way this can happen is if the image header is so
    // large (10mb+) that our attempt to use inJustDecodeBounds fails and we're forced to decode the
    // full size image.
    if (sourceWidth == -1 || sourceHeight == -1) {
      isHardwareConfigAllowed = false;
    }

    int orientation = imageReader.getImageOrientation();
    int degreesToRotate = TransformationUtils.getExifOrientationDegrees(orientation);
    boolean isExifOrientationRequired = TransformationUtils.isExifOrientationRequired(orientation);

    int targetWidth =
        requestedWidth == Target.SIZE_ORIGINAL
            ? (isRotationRequired(degreesToRotate) ? sourceHeight : sourceWidth)
            : requestedWidth;
    int targetHeight =
        requestedHeight == Target.SIZE_ORIGINAL
            ? (isRotationRequired(degreesToRotate) ? sourceWidth : sourceHeight)
            : requestedHeight;

    ImageType imageType = imageReader.getImageType();

    //计算缩放比例,结果会体现在options参数中
    calculateScaling(
        imageType,
        imageReader,
        callbacks,
        bitmapPool,
        downsampleStrategy,
        degreesToRotate,
        sourceWidth,
        sourceHeight,
        targetWidth,
        targetHeight,
        options);
        
    calculateConfig(
        imageReader,
        decodeFormat,
        isHardwareConfigAllowed,
        isExifOrientationRequired,
        options,
        targetWidth,
        targetHeight);
	//计算sdk版本是否大于KITKAT,在该系统及之前 图片复用仅支持大小相同的位图 
    boolean isKitKatOrGreater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    //下面的判断,来计算是否在BitmapPool中 是否有bitmap可以被复用,如果有就把bitmap 设置到options.inBitmap
    //这样在根据options 去解析生成bitmap的时候,就不需要再次分配内存了,避免了内存抖动
    // Prior to KitKat, the inBitmap size must exactly match the size of the bitmap we're decoding.
    if ((options.inSampleSize == 1 || isKitKatOrGreater) && shouldUsePool(imageType)) {
      int expectedWidth;
      int expectedHeight;
      if (sourceWidth >= 0
          && sourceHeight >= 0
          && fixBitmapToRequestedDimensions
          && isKitKatOrGreater) {
        expectedWidth = targetWidth;
        expectedHeight = targetHeight;
      } else {
        float densityMultiplier =
            isScaling(options) ? (float) options.inTargetDensity / options.inDensity : 1f;
        int sampleSize = options.inSampleSize;
        int downsampledWidth = (int) Math.ceil(sourceWidth / (float) sampleSize);
        int downsampledHeight = (int) Math.ceil(sourceHeight / (float) sampleSize);
        expectedWidth = Math.round(downsampledWidth * densityMultiplier);
        expectedHeight = Math.round(downsampledHeight * densityMultiplier);

      }
      // If this isn't an image, or BitmapFactory was unable to parse the size, width and height
      // will be -1 here.
      if (expectedWidth > 0 && expectedHeight > 0) {
        //该函数会在bitmapPool中查找符合大小的bitmap ,如果找到了就设置给inBitmap
        setInBitmap(options, bitmapPool, expectedWidth, expectedHeight);
      }
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
      boolean isP3Eligible =
          preferredColorSpace == PreferredColorSpace.DISPLAY_P3
              && options.outColorSpace != null
              && options.outColorSpace.isWideGamut();
      options.inPreferredColorSpace =
          ColorSpace.get(isP3Eligible ? ColorSpace.Named.DISPLAY_P3 : ColorSpace.Named.SRGB);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      options.inPreferredColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
    }
	//根据options 把流解析为Bitmap
    Bitmap downsampled = decodeStream(imageReader, options, callbacks, bitmapPool);
    callbacks.onDecodeComplete(bitmapPool, downsampled);

    Bitmap rotated = null;
    if (downsampled != null) {
      // If we scaled, the Bitmap density will be our inTargetDensity. Here we correct it back to
      // the expected density dpi.
      downsampled.setDensity(displayMetrics.densityDpi);

      rotated = TransformationUtils.rotateImageExif(bitmapPool, downsampled, orientation);
      if (!downsampled.equals(rotated)) {
        bitmapPool.put(downsampled);
      }
    }

    return rotated;
  }

至此已经得到了解析后的资源了,接下来就是要显示到指定的ImageView控件上

回到上述方法中注释处4 Decodejob  notifyEncodeAndRelease(resource, currentDataSource);

private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {

        if (resource instanceof Initializable) {
            ((Initializable) resource).initialize();
        }

        Resource<R> result = resource;
        LockedResource<R> lockedResource = null;
        if (deferredEncodeManager.hasResourceToEncode()) {
            lockedResource = LockedResource.obtain(resource);
            result = lockedResource;
        }
        // 通知主线程回调,加载图片
        notifyComplete(result, dataSource);
        // 更新状态为编码
        stage = Stage.ENCODE;
        try {
            //是否可以将转换的图片缓存
            if (deferredEncodeManager.hasResourceToEncode()) {
                //磁盘缓存入口
                deferredEncodeManager.encode(diskCacheProvider, options);
            }
        } finally {
            if (lockedResource != null) {
                lockedResource.unlock();
            }
        }
        // Call onEncodeComplete outside the finally block so that it's not called if the encode process
        // throws.
        onEncodeComplete();
    }
    private void notifyComplete(Resource<R> resource, DataSource dataSource) {
        setNotifiedOrThrow();
         // 这个callback 就是 EngineJob对象,  是在创建Decodejob的时候,传递进来,第本节 第9步
        callback.onResourceReady(resource, dataSource);
    }

我们直接看 EngineJob 的 onResourceReady 回调函数

  @Override
  public void onResourceReady(Resource<R> resource, DataSource dataSource) {
    synchronized (this) {
      this.resource = resource;
      this.dataSource = dataSource;
    }
    notifyCallbacksOfResult();
  }


  @Synthetic
  void notifyCallbacksOfResult() {
    ResourceCallbacksAndExecutors copy;
    Key localKey;
    EngineResource<?> localResource;
    synchronized (this) {
      stateVerifier.throwIfRecycled();
      if (isCancelled) {
        resource.recycle();
        release();
        return;
      } else if (cbs.isEmpty()) {
      ... 
      }
      engineResource = engineResourceFactory.build(resource, isCacheable);
      hasResource = true;
      copy = cbs.copy();
      incrementPendingCallbacks(copy.size() + 1);

      localKey = key;
      localResource = engineResource;
    }

    //回调上层 Engine 任务完成了
    listener.onEngineJobComplete(this, localKey, localResource);

    //遍历资源回调给 ImageViewTarget 
    for (final ResourceCallbackAndExecutor entry : copy) {
      entry.executor.execute(new CallResourceReady(entry.cb));
    }
    decrementPendingCallbacks();
  }

通过上面 EngineJob 的 onResourceReady 回调函数 主要做了 2 件事儿

  1. 通知上层任务完成。
  2. 回调 ImageViewTarget 用于展示数据。

我们看下 listener.onEngineJobComplete 具体实现

  @SuppressWarnings("unchecked")
  @Override
  public synchronized void onEngineJobComplete(
      EngineJob<?> engineJob, Key key, EngineResource<?> resource) {
    if (resource != null) {
      resource.setResourceListener(key, this);
			//收到下游返回回来的资源,添加到活动缓存中
      if (resource.isCacheable()) {
        activeResources.activate(key, resource);
      }
    }

    jobs.removeIfCurrent(key, engineJob);
  }

后通知 ImageViewTarget ,我们看EngineJob 方法中 遍历资源回调给 ImageViewTarget  中的操作

//遍历资源回调给 ImageViewTarget 
    for (final ResourceCallbackAndExecutor entry : copy) {
      entry.executor.execute(new CallResourceReady(entry.cb));
    }
  private class CallResourceReady implements Runnable {

    private final ResourceCallback cb;

    CallResourceReady(ResourceCallback cb) {
      this.cb = cb;
    }

    @Override
    public void run() {
      synchronized (EngineJob.this) {
        if (cbs.contains(cb)) {
         ...
          //返回准备好的资源
          callCallbackOnResourceReady(cb);
          removeCallback(cb);
        }
        decrementPendingCallbacks();
      }
    }
  }

最后我们继续跟 callCallbackOnResourceReady

  @Synthetic
  synchronized void callCallbackOnResourceReady(ResourceCallback cb) {
    try {
      //回调给 SingleRequest
      cb.onResourceReady(engineResource, dataSource);
    } catch (Throwable t) {
      throw new CallbackException(t);
    }
  }


最后看下  SingleRequest onResourceReady 回调

 public synchronized void onResourceReady(Resource<?> resource, DataSource dataSource) {
    stateVerifier.throwIfRecycled();
    loadStatus = null;
   
  ....
		
    Object received = resource.get();
    if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
      releaseResource(resource);

      ...
        
      onLoadFailed(exception);
      return;
    }

    if (!canSetResource()) {
      releaseResource(resource);
      status = Status.COMPLETE;
      return;
    }

   //当资源准备好的时候
    onResourceReady((Resource<R>) resource, (R) received, dataSource);
  }


private synchronized void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
   
  ...

      anyListenerHandledUpdatingTarget |=
          targetListener != null
              && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);

      if (!anyListenerHandledUpdatingTarget) {
        Transition<? super R> animation =
            animationFactory.build(dataSource, isFirstResource);
        //回调给目标 ImageViewTarget 资源准备好了
        target.onResourceReady(result, animation);
      }
    } finally {
      isCallingCallbacks = false;
    }

  	//加载成功
    notifyLoadSuccess();
  }

public abstract class ImageViewTarget<Z> extends ViewTarget<ImageView, Z>
    implements Transition.ViewAdapter { 
  
  ...
    


  private void setResourceInternal(@Nullable Z resource) {
    //调用 setResource 函数,将资源显示出来
    setResource(resource);
    ...
  }
}

这里ImageViewTarget 的实现类中  BitmapImageViewTarget 和 DrawableImageViewTarget 中具体显示方法如下

public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {

  public DrawableImageViewTarget(ImageView view) {
    super(view);
  }

  // Public API.
  @SuppressWarnings({"unused", "deprecation"})
  @Deprecated
  public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }

  @Override
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
  }
}
public class BitmapImageViewTarget extends ImageViewTarget<Bitmap> {
  
  @SuppressWarnings("WeakerAccess")
  public BitmapImageViewTarget(ImageView view) {
    super(view);
  }

  
  @SuppressWarnings({"unused", "deprecation"})
  @Deprecated
  public BitmapImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }

  
  @Override
  protected void setResource(Bitmap resource) {
    view.setImageBitmap(resource);
  }
}

通过 setResouse 方法  把图片信息显示出来。

至此,Glide 源码就大致分析完了  

总结  

总的来说,图片加载流程大致可分为 4 步:

  1. 准备工作
  2. 内存缓存
  3. 数据加载
  4. 解码显示

准备工作包括:

  1. 添加一个 Fragment 到对应的 Activity/Fragment 上面,监听生命周期。以控制请求的暂停执行、恢复执行,或清理资源
  2. 递归构建 Request。以协调主图、缩略图、出错图的加载请求。缩略图和主图同时加载,如果主图先加载完成,则取消缩略图的加载请求,否则先显示缩略图,等主图加载完成后再清除。出错图则是在主图加载失败后才开始加载并显示
  3. 获取目标尺寸。以 ImageView 为例,尺寸是在 ViewTreeObserver 的 onPreDraw 方法回调后获取的。
  4. 设置占位图。占位图是直接调用 setImageDrawable 方法设置的,因此不需要和主图协调

内存缓存包括两部分:

  1. 活跃的资源,即加载完成后已回调给 Target 并且未被释放的资源,可以简单理解为正在显示的图片,通过引用计数判断具体释放的时机
  2. 内存缓存,即不再显示,但仍处于内存中未被 LRU 算法移除的资源

数据加载包括两部分:

  1. 从磁盘缓存中加载
  2. 从目标地址中加载

磁盘缓存又分为两部分:

  1. 从缩放、变换后的文件缓存中查找
  2. 如果找不到,再到原始的图片缓存中查找

目标地址有很多种,比如本地文件路径、文件句柄、Asset、服务器链接等。

成功获取到数据之后:

  1. 首先需要将原始图像数据缓存到本地磁盘中
  2. 接着将数据解码为 Bitmap/Drawable 等资源类型,同时应用圆角等变换效果(如果不是从变换后的文件缓存中获取的话)
  3. 然后才能回调给 Target 并显示
  4. 最后还需要将缩放、变换后的图片数据写入到磁盘缓存,并清理资源

Target 显示图片时还会判断是否需要执行过渡动画,如果需要,则执行过渡动画后再显示资源。显示资源时,会判断该资源类型是否为 gif 图,如果是,则开始执行动画,否则直接显示即可。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值