美文网首页开源框架
Glide图片加载三步曲源码解析

Glide图片加载三步曲源码解析

作者: Steven_SHH | 来源:发表于2019-11-22 10:48 被阅读0次

    Glide图片加载框架大家都应该不会陌生,集成使用起来非常的简单,但是之前都没怎么看过Glide的源码,现在自己照着源码钻研一下,看看到底是如何通过这三个方法,就能加载出图片,做到这么强大的功能的。源码基于Glide4.9.0


    Glide的基本使用

    Glide最基本的使用方法就是三步,先with(),再load(),最后就是into(),然而就是这么三步简单的代码,就能将图片加载到我们的ImageView中,那么通过调用这三个方法到底是如何实现图片加载的呢?此次就对这个三个方法进行解析。

    Glide.with(this).load(url).into(ImageView);
    

    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);
    }
    
    
    @SuppressWarnings("deprecation")
    @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);
    }
    
    
    
    // Glide中的getRetriever(Context)方法
    @NonNull
    private static RequestManagerRetriever getRetriever(@Nullable Context context) {
      ...// 会判断context不能为空,否者抛出异常
      // 通过Glide.get(context)获取或创建Glide单例对象
      // 通过glide对象获取RequestManagerRetriever对象
      return Glide.get(context).getRequestManagerRetriever();
    }
    
    

    由以上源码可以看出with()方法一共做了两件事

    • 调用getRetriever()方法,获取到RequestManagerRetriever对象
    • 然后通过RequestManagerRetriever对象调用get()方法,获取到一个RequestManager请求管理器对象

    创建或获取Glide单例对象

    // Glide中的get(Context)方法,获取线程安全的Glide单例对象
    @NonNull
    public static Glide get(@NonNull Context context) {
      if (glide == null) {
        synchronized (Glide.class) {
          if (glide == null) {
            checkAndInitializeGlide(context);
          }
        }
      }
    
      return glide;
    }
    
    // 检查Glide是否正在初始化,未在初始化则进行初始化
    private static void checkAndInitializeGlide(@NonNull Context context) {
    // 检查Glide是否正在初始化,保证Glide只被初始化一次
      if (isInitializing) {
        throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
            + " use the provided Glide instance instead");
      }
      isInitializing = true;
      initializeGlide(context);
      isInitializing = false;
    }
    
    // 初始化Glide
    private static void initializeGlide(@NonNull Context context) {
      // 创建了一个GlideBuilder()实例传入initializeGlide()方法
      initializeGlide(context, new GlideBuilder());
    }
    
    // 初始化Glide
    @SuppressWarnings("deprecation")
    private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
      Context applicationContext = context.getApplicationContext();
      // 获取@GlideModule注解驱动生成的GeneratedAppGlideModuleImpl和GeneratedAppGlideModuleFactory类
      GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
      List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
      if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
        manifestModules = new ManifestParser(applicationContext).parse();
      }
    
      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();
        }
      }
    
      // ... 日志输出
    
      // 尝试从注解生成的annotationGeneratedModule中获取RequestManager的构造工厂对象
      RequestManagerRetriever.RequestManagerFactory factory =
          annotationGeneratedModule != null
              ? annotationGeneratedModule.getRequestManagerFactory() : null;
      // 向GlideBuilder中设置管理器工厂
      builder.setRequestManagerFactory(factory);
      for (com.bumptech.glide.module.GlideModule module : manifestModules) {
        module.applyOptions(applicationContext, builder);
      }
      if (annotationGeneratedModule != null) {
        annotationGeneratedModule.applyOptions(applicationContext, builder);
      }
    
      // 通过GlideBuilder中的build()方法创建Glide对象
      Glide glide = builder.build(applicationContext);
      for (com.bumptech.glide.module.GlideModule module : manifestModules) {
        module.registerComponents(applicationContext, glide, glide.registry);
      }
      if (annotationGeneratedModule != null) {
        annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
      }
      applicationContext.registerComponentCallbacks(glide);
      // 给Glide对象赋值
      Glide.glide = glide;
    }
    
    
    

    可以看到通过GlideBuilder类中的build()方法创建Glide对象,并且保存在Glide类中的静态成员变量glide中


    Glide对象的创建过程

    
    @NonNull
    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复用池
      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(),
                GlideExecutor.newAnimationExecutor(),
                isActiveResourceRetentionAllowed);
      }
    
      if (defaultRequestListeners == null) {
        defaultRequestListeners = Collections.emptyList();
      } else {
        defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
      }
    
      // 创建了一个RequestManagerRetriever对象
      RequestManagerRetriever requestManagerRetriever =
          new RequestManagerRetriever(requestManagerFactory);
    
      // 创建Glide对象
      return new Glide(
          context,
          engine,
          memoryCache,
          bitmapPool,
          arrayPool,
          requestManagerRetriever,
          connectivityMonitorFactory,
          logLevel,
          defaultRequestOptions.lock(),
          defaultTransitionOptions,
          defaultRequestListeners,
          isLoggingRequestOriginsEnabled);
    }
    
    
    // Glide的构造方法
    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) {
    
      // 将GlideBuild中的管理引擎,线程池,缓存池等保存
      this.engine = engine;
      this.bitmapPool = bitmapPool;
      this.arrayPool = arrayPool;
      this.memoryCache = memoryCache;
      this.requestManagerRetriever = requestManagerRetriever;
      this.connectivityMonitorFactory = connectivityMonitorFactory;
    
      ...
      registry = new Registry();
    
      // 创建一个Registry,管理组件注册,以扩展或替换Glide的默认加载、解码和编码逻辑。
      ...
    
      // 创建一个GlideContext上下文
      glideContext =
          new GlideContext(
              context,
              arrayPool,
              registry,
              imageViewTargetFactory,
              defaultRequestOptions,
              defaultTransitionOptions,
              defaultRequestListeners,
              engine,
              isLoggingRequestOriginsEnabled,
              logLevel);
    }
    
    

    Glide的创建过程非常的复杂,构建了一系列的线程池,内存缓存策略,对象复用池,工厂类等,这里就不再进行深入探索。
    在创建GlideBuilder.build的时候, 创建了一个RequestManagerRetriever对象并且传递到了Glide构造方法,并且进行保存,
    于是通过Glide.getRequestManagerRetriever() 就可以获取到RequestManagerRetriever这个对象了


    获取RequestManage对象

    // 首先通过Glide对象获取RequestManagerRetriever对象
    @NonNull
    public RequestManagerRetriever getRequestManagerRetriever() {
      return requestManagerRetriever;
    }
    
    
    // 然后通过RequestManagerRetriever对象获取RequestManager对象(RequestManagerRetriever类中的方法) 
    @NonNull
    public RequestManager get(@NonNull Context context) {
      if (context == null) {
        throw new IllegalArgumentException("You cannot start a load on a null Context");
      } else if (Util.isOnMainThread() && !(context instanceof Application)) {
        // 判断当前线程是在主线程中并且传入的context不是ApplicationContext
        // 根据传入的context调用不同的get()方法
        if (context instanceof FragmentActivity) {
          return get((FragmentActivity) context);
        } else if (context instanceof Activity) {
          return get((Activity) context);
        } else if (context instanceof ContextWrapper) {
          return get(((ContextWrapper) context).getBaseContext());
        }
      }
    
      // 如果是ApplicationContext直接调用getApplicationManager()方法获取RequestManager对象
      return getApplicationManager(context);
    }
    
    
    // 传入ApplicationContext获取RequestManager对象(RequestManagerRetriever类中的方法) 
    @NonNull
    private RequestManager getApplicationManager(@NonNull Context context) {
      // 传入ApplicationContext或者在子线程时,会调用该方法创建或获取RequestManager对象
      if (applicationManager == null) {
        synchronized (this) {
          if (applicationManager == null) {
            Glide glide = Glide.get(context.getApplicationContext());
            // 通过RequestManagerFactory接口中的build方法,创建RequestManager对象...todo(没看到在哪里实现的)
            applicationManager =
                factory.build(
                    glide,
                    new ApplicationLifecycle(),
                    new EmptyRequestManagerTreeNode(),
                    context.getApplicationContext());
          }
        }
      }
    
      return applicationManager;
    }
    
    // 传入的context为FragmentActivity
    @NonNull
    public RequestManager get(@NonNull FragmentActivity activity) {
      // 判断如果是子线程,则使用get(ApplicationContext)获取RequestManager对象
      if (Util.isOnBackgroundThread()) {
        return get(activity.getApplicationContext());
      } else {
        // 判断当前activity是否已经销毁,销毁会抛出异常
        assertNotDestroyed(activity);
        FragmentManager fm = activity.getSupportFragmentManager();
        // 通过supportFragmentGet方法获取RequestManager对象
        return supportFragmentGet(
            activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
      }
    }
    
    // 传入的context为Fragment
    @NonNull
    public RequestManager get(@NonNull Fragment fragment) {
      Preconditions.checkNotNull(fragment.getActivity(),
            "You cannot start a load on a fragment before it is attached or after it is destroyed");
      if (Util.isOnBackgroundThread()) {
        return get(fragment.getActivity().getApplicationContext());
      } else {
        FragmentManager fm = fragment.getChildFragmentManager();
        return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
      }
    }
    
    // 传入的context为Activity
    @SuppressWarnings("deprecation")
    @NonNull
    public RequestManager get(@NonNull Activity activity) {
      if (Util.isOnBackgroundThread()) {
        return get(activity.getApplicationContext());
      } else {
        assertNotDestroyed(activity);
        android.app.FragmentManager fm = activity.getFragmentManager();
        return fragmentGet(
            activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
      }
    }
    
    
    // 传入的context为View
    @SuppressWarnings("deprecation")
    @NonNull
    public RequestManager get(@NonNull View view) {
      if (Util.isOnBackgroundThread()) {
        return get(view.getContext().getApplicationContext());
      }
    
      Preconditions.checkNotNull(view);
      Preconditions.checkNotNull(view.getContext(),
          "Unable to obtain a request manager for a view without a Context");
      Activity activity = findActivity(view.getContext());
      // The view might be somewhere else, like a service.
      if (activity == null) {
        return get(view.getContext().getApplicationContext());
      }
    
    
      if (activity instanceof FragmentActivity) {
        Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
        return fragment != null ? get(fragment) : get(activity);
      }
    
      // Standard Fragments.
      android.app.Fragment fragment = findFragment(view, activity);
      if (fragment == null) {
        return get(activity);
      }
      return get(fragment);
    }
    
    // 判断当前activity是否已经销毁
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private static void assertNotDestroyed(@NonNull Activity activity) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
        throw new IllegalArgumentException("You cannot start a load for a destroyed activity");
      }
    }
    
    
    // 通过supportFragmentGet方法获取RequestManager对象
    @NonNull
    private RequestManager supportFragmentGet(
        @NonNull Context context,
        @NonNull FragmentManager fm,
        @Nullable Fragment parentHint,
        boolean isParentVisible) {
      // 通过getSupportRequestManagerFragment方法创建一个隐藏的Fragment
      SupportRequestManagerFragment current =
          getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
      // 通过该fragment获取到RequestManager对象
      RequestManager requestManager = current.getRequestManager();
      if (requestManager == null) {
        // 如果requestManager对象为空,则通过RequestManagerFactory构建一个
        Glide glide = Glide.get(context);
        requestManager =
            factory.build(
                glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
        // 将requestManager保存到当前fragment中
        current.setRequestManager(requestManager);
      }
      return requestManager;
    }
    
    
    @SuppressWarnings({"deprecation", "DeprecatedIsStillUsed"})
    @Deprecated
    @NonNull
    private RequestManager fragmentGet(@NonNull Context context,
        @NonNull android.app.FragmentManager fm,
        @Nullable android.app.Fragment parentHint,
        boolean isParentVisible) {
      //  从 Activity 中获取一个RequestManagerFragment, 用于监管Activity的声明周期
      RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
      // 获取Fragment中保存的当前页面的请求管理器 
      RequestManager requestManager = current.getRequestManager();
      // 不存在则创建一个请求管理器保存在RequestManagerFragment中
      if (requestManager == null) {
        Glide glide = Glide.get(context);
        requestManager =
            factory.build(
                glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
        current.setRequestManager(requestManager);
      }
      return requestManager;
    }
    
    
    // 创建一个隐藏的Fragment
    @NonNull
    private SupportRequestManagerFragment getSupportRequestManagerFragment(
        @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
      //  从FragmentManager中获取这个Fragment
      SupportRequestManagerFragment current =
          (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
      // 不存在则添加一个
      if (current == null) {
        // 从pendingSupportRequestManagerFragments中获取一个
        current = pendingSupportRequestManagerFragments.get(fm);
        if (current == null) {
          // 没有获取到则创建一个
          current = new SupportRequestManagerFragment();
          current.setParentFragmentHint(parentHint);
          if (isParentVisible) {
            current.getGlideLifecycle().onStart();
          }
          // 添加到等待被添加的缓存中
          pendingRequestManagerFragments.put(fm, current);
          // 因为添加到FragmentManager有延迟
          // 防止同一时间创建了两个RequestManagerFragment对象添加到Activity中
          pendingSupportRequestManagerFragments.put(fm, current);
          // 添加到FragmentManager中
          fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
          // 加到FragmentManager成功, 通过Handler移除这个缓存
          handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
        }
      }
      return current;
    }
    
    

    从源码中可以看到,RequestManagerRetriever.get()方法会判断Context的类型,根据传入不同的的类型,获取到不同RequestManager对象

    • 若在主线程并且不为Application类型的Context则找寻其依赖的Activity
    • 若非主线程或为Application类型的Context,则使用ApplicationManager

    传入Application类型的Context处理是比较简单的,因为Application对象的生命周期即应用程序的生命周期,因此Glide并不需要做什么特殊的处理,它自动就是和应用程序的生命周期是同步的,如果应用程序关闭的话,Glide的加载也会同时终止。

    而非ApplictionContext则主要是在Activity页面中添加一个RequestManagerFragment实例, 以便用于监听Activity的生命周期, 然后给这个Fragment注入一个RequestManager。因为Glide并没有办法知道Activity的生命周期,所以采用这种添加隐藏Fragment的技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,当Activity被销毁后,Glide就能捕获到并且停止加载图片了。


    load()方法解析

    RequestManager类中load()方法同样很很多个重载方法,这里只列出常用的几个,会根据传入的参数类型调用RequestBuilder类中的不同的load()重载方法

    //RequestManager类中的方法
    
    @NonNull
    @CheckResult
    @Override
    public RequestBuilder<Drawable> load(@Nullable Bitmap bitmap) {
      // 通过调用asDrawable()方法,创建出一个RequestBuilder对象
      return asDrawable().load(bitmap);
    }
    
    @NonNull
    @CheckResult
    @Override
    public RequestBuilder<Drawable> load(@Nullable Drawable drawable) {
      return asDrawable().load(drawable);
    }
    
    @NonNull
    @CheckResult
    @Override
    public RequestBuilder<Drawable> load(@Nullable String string) {
      return asDrawable().load(string);
    }
    
    
    @NonNull
    @CheckResult
    @Override
    public RequestBuilder<Drawable> load(@Nullable File file) {
      return asDrawable().load(file);
    }
    
    
    @NonNull
    @CheckResult
    public RequestBuilder<Drawable> asDrawable() {
      // 全部都以Drawable类型传入as方法
      return as(Drawable.class);
    }
    
    @NonNull
    @CheckResult
    public <ResourceType> RequestBuilder<ResourceType> as(
        @NonNull Class<ResourceType> resourceClass) {
      // 创建出RequestBuilder对象
      return new RequestBuilder<>(glide, this, resourceClass, context);
    }
    
    

    其实load方法中,如果不去深究创建RequestBuilder对象的话,是非常简单的,所有重载方法都会先调用asDrawable()方法,传入Drawable类型,创建出RequestBuilder对象,然后再调用RequestBuilder中的load()方法


    RequestBuilder

    // RequestBuilder的构造方法
    protected RequestBuilder(
        @NonNull Glide glide,
        RequestManager requestManager,
        Class<TranscodeType> transcodeClass,
        Context context) {
      this.glide = glide;
      this.requestManager = requestManager;
      this.transcodeClass = transcodeClass;
      this.context = context;
      this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
      this.glideContext = glide.getGlideContext();
    
      // 初始化requestManager中默认的请求监听
      initRequestListeners(requestManager.getDefaultRequestListeners());
      // 根据requestManager中的默认请求选项进行赋值,也就是我们经常用的占位图,错误图,缓存策略等选项
      apply(requestManager.getDefaultRequestOptions());
    }
    
    
    @NonNull
    @CheckResult
    @Override
    public RequestBuilder<TranscodeType> load(@Nullable Bitmap bitmap) {
      // 传入Bitmap时会设置不使用磁盘缓存
      return loadGeneric(bitmap)
          .apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
    }
    
    @NonNull
    @CheckResult
    @Override
    public RequestBuilder<TranscodeType> load(@Nullable Drawable drawable) {
       // 传入Drawable时也会设置不使用磁盘缓存
      return loadGeneric(drawable)
          .apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
    }
    
    @NonNull
    @Override
    @CheckResult
    public RequestBuilder<TranscodeType> load(@Nullable String string) {
      return loadGeneric(string);
    }
    
    @NonNull
    @CheckResult
    @Override
    public RequestBuilder<TranscodeType> load(@Nullable File file) {
      return loadGeneric(file);
    }
    
    // 最终都会调用该方法
    @NonNull
    private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
      this.model = model;
      // 标识是否已经调用了load()方法,在调用into()方法是会做判断,没有设置为true会抛出异常
      // 也就是在调用into()方法前,必须调用load()方法
      isModelSet = true;
      return this;
    }
    

    into()方法

    @NonNull
    public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
      // 判断是否在主线程中执行
      Util.assertMainThread();
      // 判空操作,view不能为空
      Preconditions.checkNotNull(view);
    
      // 根据view的scaleType重构RequestOptions
      BaseRequestOptions<?> requestOptions = this;
      if (!requestOptions.isTransformationSet()
          && requestOptions.isTransformationAllowed()
          && view.getScaleType() != null) {
        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.
        }
      }
    
      // 调用into方法,创建执行请求
      return into(
          glideContext.buildImageViewTarget(view, transcodeClass),
          /*targetListener=*/ null,
          requestOptions,
          Executors.mainThreadExecutor());
    }
    
    
    
    private <Y extends Target<TranscodeType>> Y into(
        @NonNull Y target,
        @Nullable RequestListener<TranscodeType> targetListener,
        BaseRequestOptions<?> options,
        Executor callbackExecutor) {
      Preconditions.checkNotNull(target);
      // 调用into()方法之前 必须要先调用load()方法,isModelSet会在调用load方法之后赋值为true
      if (!isModelSet) {
        throw new IllegalArgumentException("You must call #load() before calling #into()");
      }
    
      // 调用buildRequest()方法,构建一个Request请求
      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;
      }
    
      // 清除target之前的请求,释放资源
      requestManager.clear(target);
      //给ViewTarget设置这个Request请求,即Glide加载图片的请求
      target.setRequest(request);
      // 调用RequestManager.track()方法执行请求
      requestManager.track(target, request);
    
      return target;
    }
    

    可以看到into()方法的代码其实并不多,但是里面的涉及到的调用却嵌套了很多层,现在就一步一步的解析它里面调用的方法。


    配置options

    加载图片的时候会根据viewscaleType重构RequestOptions,所以先对这个进行解析,这里会根据不同的scaleType方式,调用不同的方法,
    不过基本上差不多,这里选取其中的一种的requestOptions.clone().optionalFitCenter()进行解析

    public abstract class BaseRequestOptions<T extends BaseRequestOptions<T>> implements Cloneable {
    
      @NonNull
      private Options options = new Options();
      @NonNull
      private Map<Class<?>, Transformation<?>> transformations = new CachedHashCodeArrayMap<>();
    
    }
    
    // clone方法,主要是对一些资源参数进行初始化赋值
    public T clone() {
      try {
        BaseRequestOptions<?> result = (BaseRequestOptions<?>) super.clone();
        result.options = new Options();
        result.options.putAll(options);
        result.transformations = new CachedHashCodeArrayMap<>();
        result.transformations.putAll(transformations);
        result.isLocked = false;
        // 赋值不进行自动拷贝
        result.isAutoCloneEnabled = false;
        return (T) result;
      } catch (CloneNotSupportedException e) {
        throw new RuntimeException(e);
      }
    }
    
    public T optionalFitCenter() {
      // DownsampleStrategy描述降采样压缩的策略
      // FitCenter 描述图像变化方式
      return optionalScaleOnlyTransform(DownsampleStrategy.FIT_CENTER, new FitCenter());
    }
    
    private T optionalScaleOnlyTransform(
        @NonNull DownsampleStrategy strategy, @NonNull Transformation<Bitmap> transformation) {
      return scaleOnlyTransform(strategy, transformation, false /*isTransformationRequired*/);
    }
    
    private T scaleOnlyTransform(
        @NonNull DownsampleStrategy strategy,
        @NonNull Transformation<Bitmap> transformation,
        boolean isTransformationRequired) {
      // 这里根据传入的isTransformationRequired值,调用optionalTransform()方法
      BaseRequestOptions<T> result = isTransformationRequired
            ? transform(strategy, transformation) : optionalTransform(strategy, transformation);
      result.isScaleOnlyOrNoTransform = true;
      return (T) result;
    }
    
    final T optionalTransform(@NonNull DownsampleStrategy downsampleStrategy,
        @NonNull Transformation<Bitmap> transformation) {
      // 调用clone()方法时,赋值的false
      if (isAutoCloneEnabled) {
        return clone().optionalTransform(downsampleStrategy, transformation);
      }
    
      // 调用改方法,主要是保存options配置信息
      downsample(downsampleStrategy);
      return transform(transformation, /*isRequired=*/ false);
    }
    
    public T downsample(@NonNull DownsampleStrategy strategy) {
      return set(DownsampleStrategy.OPTION, Preconditions.checkNotNull(strategy));
    }
    
    public <Y> T set(@NonNull Option<Y> option, @NonNull Y value) {
      if (isAutoCloneEnabled) {
        return clone().set(option, value);
      }
    
      Preconditions.checkNotNull(option);
      Preconditions.checkNotNull(value);
      // 保存配置信息
      options.set(option, value);
      return selfOrThrowIfLocked();
    }
    
    T transform(
        @NonNull Transformation<Bitmap> transformation, boolean isRequired) {
      if (isAutoCloneEnabled) {
        return clone().transform(transformation, isRequired);
      }
    
      DrawableTransformation drawableTransformation =
          new DrawableTransformation(transformation, isRequired);
      // 调用了transform的重载方法, 将这个图像变化的方式作用到多种资源类型上
      transform(Bitmap.class, transformation, isRequired);
      transform(Drawable.class, drawableTransformation, isRequired);
      transform(BitmapDrawable.class, drawableTransformation.asBitmapDrawable(), isRequired);
      transform(GifDrawable.class, new GifDrawableTransformation(transformation), isRequired);
      return selfOrThrowIfLocked();
    }
    
    <Y> T transform(
        @NonNull Class<Y> resourceClass,
        @NonNull Transformation<Y> transformation,
        boolean isRequired) {
      if (isAutoCloneEnabled) {
        return clone().transform(resourceClass, transformation, isRequired);
      }
    
      Preconditions.checkNotNull(resourceClass);
      Preconditions.checkNotNull(transformation);
    
      // 添加到transformations缓存中
      transformations.put(resourceClass, transformation);
    
      fields |= TRANSFORMATION;
      isTransformationAllowed = true;
      fields |= TRANSFORMATION_ALLOWED;
      isScaleOnlyOrNoTransform = false;
      if (isRequired) {
        fields |= TRANSFORMATION_REQUIRED;
        isTransformationRequired = true;
      }
      return selfOrThrowIfLocked();
    }
    

    可以看到options配置操作,无非就是添加添加了图像变化操作, 并且设定采样方式, 分别保存在transformationsoptions


    构建Target对象

    可以看到最后调用into()方法时,调用了glideContext.buildImageViewTarget(view, transcodeClass)来构建Target对象

    public class GlideContext extends ContextWrapper {
      public <X> ViewTarget<ImageView, X> buildImageViewTarget(
          @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
        return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
      }
    }
    
    public class ImageViewTargetFactory {
      @NonNull
      @SuppressWarnings("unchecked")
      public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
          @NonNull Class<Z> clazz) {
        //  根据目标编码的类型来创建不同的ViewTarget对象, 因为我们没有asBitmap, 因此这里为Drawable
        if (Bitmap.class.equals(clazz)) {
          return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
        } else if (Drawable.class.isAssignableFrom(clazz)) {
          return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
        } else {
          throw new IllegalArgumentException(
              "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
        }
      }
    }
    

    buildRequest创建Request

    可以看到into()方法中,调用了buildRequest()方法来创建一个Request
    Request request = buildRequest(target, targetListener, options, callbackExecutor);这里不具体去看到底是如何创建的,最终就是调用SingleRequest.obtain构建一个Request的实例对象

    public class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>>
       implements Cloneable,
       ModelTypes<RequestBuilder<TranscodeType>> {
    
         private Request buildRequest(
         Target<TranscodeType> target,
         @Nullable RequestListener<TranscodeType> targetListener,
         BaseRequestOptions<?> requestOptions,
         Executor callbackExecutor) {
       return buildRequestRecursive(...);
     }
    
     // buildRequestRecursive方法中通过调用buildThumbnailRequestRecursive方法返回Request
     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) {
    
     ...
    
     ErrorRequestCoordinator errorRequestCoordinator = null;
     if (errorBuilder != null) {
       errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
       parentCoordinator = errorRequestCoordinator;
     }
    
     Request mainRequest =
         buildThumbnailRequestRecursive(...);
    
     if (errorRequestCoordinator == null) {
       return mainRequest;
     }
    
     // 而该方法中通过obtainRequest创建Request
     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) {
    
         ...
    
         // Base case: no thumbnail.
         return obtainRequest(...);
       
     }
    
     // 最终通过SingleRequest.obtain返回一个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(...);
     }
    
    }
    

    Request的分发

    可以看到最后调用了requestManager.track(target, request);去分发请求,接下来我们就看看到底这个请求是如何进行分发的

    public class RequestManager implements LifecycleListener,
      ModelTypes<RequestBuilder<Drawable>> {
    
      synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
        // 将加载图片的Target保存到Set集合targets中
        targetTracker.track(target);
        // 执行请求
        requestTracker.runRequest(request);
      }
    
    }
    
    public final class TargetTracker implements LifecycleListener {
      private final Set<Target<?>> targets =
          Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());
    
      public void track(@NonNull Target<?> target) {
        targets.add(target);
      }
     } 
    
    
    public class RequestTracker {
    
      public void runRequest(@NonNull Request request) {
        requests.add(request);
        if (!isPaused) {
          // 开始执行任务
          request.begin();
        } else {
          request.clear();
          pendingRequests.add(request);
        }
      }
    
    }
    
    
    public final class SingleRequest<R> implements Request,
        SizeReadyCallback,
        ResourceCallback,
        FactoryPools.Poolable {
    
      @Override
      public synchronized void begin() {
    
        ...
        // 正在运行
        if (status == Status.RUNNING) {
          throw new IllegalArgumentException("Cannot restart a running request");
        }
    
        // 资源已经加载完成
        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);
        }
    
        if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
            && canNotifyStatusChanged()) {
          target.onLoadStarted(getPlaceholderDrawable());
        }
    
      }
    
    
    @Override
    public synchronized void onSizeReady(int width, int height) {
      stateVerifier.throwIfRecycled();
      
      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.load()方法
      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;
      }
      if (IS_VERBOSE_LOGGABLE) {
        logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
      }
    }
    
    }
    

    任务的创建engine.load()

    在尺寸准备好后,就会在onSizeReady中调用engine.load()去构建任务

    public class Engine implements EngineJobListener,
        MemoryCache.ResourceRemovedListener,
        EngineResource.ResourceListener {
    
      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); 
                   
        // 从ActiveResources中查找key对应的资源
        EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
        if (active != null) {
          // 若存在, 则直接回调onResourceReady处理后续操作
          cb.onResourceReady(active, DataSource.MEMORY_CACHE);
          return null;
        }
    
        // 从缓存中查找key对应的资源
        EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
        if (cached != null) {
          // 若缓存存在, 则直接回调onResourceReady处理后续操作
          cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
          return null;
        }
    
        // 查找key对应的任务
        EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
        if (current != null) {
          // 如果存在,说明这个任务已经正在执行了, 无需再次构建执行
          current.addCallback(cb, callbackExecutor);
          // 返回加载的状态
          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);
      }
    }
    

    可以看到Engine.load中的事情非常的重要

    • 构建这个请求的 key
    • 从缓存中查找key对应的资源, 若存在直接回onResourceReady表示资源准备好了
      • ActiveResources中查找
      • Cache缓存中查找
    • 从缓存中查找key对应的任务
      • 若存在则说明无需再次获取资源
      • 构建新的任务
        • 构建引擎任务EngineJob
        • 引擎的任务为解码任务DecodeJob
        • 将任务添加到缓存, 防止多次构建
        • 执行任务

    任务的执行

    class EngineJob<R> implements DecodeJob.Callback<R>,
        Poolable {
        
      private final GlideExecutor diskCacheExecutor;  
      private DecodeJob<R> decodeJob;
    
      public synchronized void start(DecodeJob<R> decodeJob) {
        this.decodeJob = decodeJob;
        // 获取线程池
        GlideExecutor executor = decodeJob.willDecodeFromCache()
            ? diskCacheExecutor : getActiveSourceExecutor();
        // 执行任务
        executor.execute(decodeJob);
      }
      
    }
    
    class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
        Runnable,
        Comparable<DecodeJob<?>>,
        Poolable {
        
      @Override      
      public void run() {
         try {
          ......
          // 调用了 runWrapped
          runWrapped();
        } catch (CallbackException e) {
          ......
        }
      }        
      
      private void runWrapped() {
        switch (runReason) {
          case INITIALIZE:
            // 1. 获取任务的场景
            stage = getNextStage(Stage.INITIALIZE);
            // 2. 获取这个场景的执行者
            currentGenerator = getNextGenerator();
            // 3. 执行者执行任务
            runGenerators();
            break;
          ......
        }
      }
      
      private Stage getNextStage(Stage current) {
        switch (current) {
          case INITIALIZE:
            // 1.1 若我们配置的缓存策略允许从资源缓存中读数据, 则返回Stage.RESOURCE_CACHE
            return diskCacheStrategy.decodeCachedResource()
                ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
          case RESOURCE_CACHE:
            // 1.2 若我们配置的缓存策略允许从源数据缓存中读数据, 则返回 Stage.DATA_CACHE
            return diskCacheStrategy.decodeCachedData()
                ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
          case DATA_CACHE:
            // 1.3 若只能允许从缓存中获取数据, 则直接FINISH, 否则返回Stage.SOURCE, 意为加载一个新的资源
            return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
          case SOURCE:
          case FINISHED:
            return Stage.FINISHED;
          default:
            throw new IllegalArgumentException("Unrecognized stage: " + current);
        }
      }
      
      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() {
        ......
        boolean isStarted = false;
        // 调用 DataFetcherGenerator.startNext() 执行了请求操作
        while (!isCancelled && currentGenerator != null
            && !(isStarted = currentGenerator.startNext())) {
          stage = getNextStage(stage);
          currentGenerator = getNextGenerator();
          if (stage == Stage.SOURCE) {
            reschedule();
            return;
          }
        }
        ......
      }
    }
    
    

    获取数据源

    class SourceGenerator implements DataFetcherGenerator,
        DataFetcher.DataCallback<Object>,
        DataFetcherGenerator.FetcherReadyCallback {
      
      private final DecodeHelper<?> helper;
      
      public boolean startNext() {
        ......
        loadData = null;
        boolean started = false;
        while (!started && hasNextModelLoader()) {
          // 1. 从 DecodeHelper 的数据加载集合中, 获取一个数据加载器
          loadData = helper.getLoadData().get(loadDataListIndex++);
          if (loadData != null
              && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
              || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
            started = true;
            // 2. 使用加载器中 fetcher 执行数据加载
            loadData.fetcher.loadData(helper.getPriority(), this);
          }
        }
        return started;
      } 
    }
    

    SourceGenerator主要有两步

    • 调用DecodeHelper.getLoadData获取当前请求的数据加载器
    • 调用加载器中的fetcher.loadData真正的执行数据加载

    获取数据加载器

    final class DecodeHelper<Transcode> {
        
      private final List<LoadData<?>> loadData = new ArrayList<>();
      private GlideContext glideContext;
      private Object model;
      private boolean isLoadDataSet;    
      
      List<LoadData<?>> getLoadData() {
        if (!isLoadDataSet) {
          isLoadDataSet = true;
          loadData.clear();
          // 1. 从 Glide 注册的 register 中获取请求 model 加载器
          List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
          // 遍历每一个 modelLoaders 
          for (int i = 0, size = modelLoaders.size(); i < size; i++) {
            // 2. 通过 modelLoaders 构建 loadData
            ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
            LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
            if (current != null) {
              // 添加到缓存
              loadData.add(current);
            }
          }
        }
        return loadData;
      }  
        
    }
    
    

    它会找到一个ModelLoader的实现类, 通过这个实现类的handles方法, 判断是否可以加载这个model
    这里我们的model以网络的URL资源举例, 它的实现类为HttpGlideUrlLoader我们看看它如何构建一个 LoadData对象的

    public class HttpGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {
      
      @Nullable private final ModelCache<GlideUrl, GlideUrl> modelCache;
      
      @Override
      public LoadData<InputStream> buildLoadData(@NonNull GlideUrl model, int width, int height,
          @NonNull Options options) {  
        GlideUrl url = model;
        .....
        int timeout = options.get(TIMEOUT);
        // 创建了一个 LoadData 对象, 并且实例化了一个 HttpUrlFetcher 给它
        return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
      }
        
    }
    
    

    对于URL的加载, 其fetcher为一个HttpUrlFetcher的实例

    执行数据加载

    获取到了数据加载器之后, SourceGeneratorstartNext中便会调用其fetcherloadData执行数据的加载了

    public class HttpUrlFetcher implements DataFetcher<InputStream> {
        
      public void loadData(@NonNull Priority priority,
          @NonNull DataCallback<? super InputStream> callback) {
        long startTime = LogTime.getLogTime();
        try {
          // 获取网络图片, 内部使用了 HttpConnection 实现, 仅仅做了重定向的处理
          InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
          // 将 inputStream 回调出去
          callback.onDataReady(result);
        } catch (IOException e) {
          ......
          callback.onLoadFailed(e);
        } finally {
          ......
        }
      }
        
    }
    
    

    HttpUrlFetcher它使用了HttpConnection发起了网络请求, 获取了数据流, 至此数据资源的获取就已经完成了, 后面要做的便是最重要的数据处理了, 它通过回调的方式将InputStream扔了出去, 最终会回溯到 DecodeJobonDataFetcherReady这个方法中

    数据源的处理

    class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
        Runnable,
        Comparable<DecodeJob<?>>,
        Poolable {
    
      private Key currentSourceKey;
      private Object currentData;
      private DataSource currentDataSource;
      private DataFetcher<?> currentFetcher;
    
      @Override
      public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
          DataSource dataSource, Key attemptedKey) {
        this.currentSourceKey = sourceKey;  // 保存数据的 key
        this.currentData = data;            // 保存数据实体
        this.currentFetcher = fetcher;      // 保存数据的获取器
        this.currentDataSource = dataSource;// 数据来源: url 为 REMOTE 类型的枚举, 表示从远程获取
        ......
        if (Thread.currentThread() != currentThread) {
          ......
        } else {
          try {
            // 调用 decodeFromRetrievedData 解析获取的数据
            decodeFromRetrievedData();
          } finally {
            ......
          }
        }
      }
    
      private void decodeFromRetrievedData() {
        Resource<R> resource = null;
        try {
          // 1\. 调用了 decodeFromData 获取资源
          resource = decodeFromData(/*HttpUrlFetcher*/currentFetcher, /*InputStream*/currentData,/*REMOTE*/ currentDataSource);
        } catch (GlideException e) {
          ......
        }
        if (resource != null) {
          // 2\. 通知外界资源获取成功了
          notifyEncodeAndRelease(resource, currentDataSource);
        } else {
          ......
        }
      }
    }
    

    可以看到对于获取到的数据, 首先要将其解码为Resource类型的资源, 然后再将资源返回给上层
    我们先看看它是如何将数据解析成 Resource(非Android系统的Resource) 资源的


    资源的获取

    class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
        Runnable,
        Comparable<DecodeJob<?>>,
        Poolable {
    
      private <Data> Resource<R> decodeFromData(DataFetcher<?> fetcher, Data data,
          DataSource dataSource) throws GlideException {
        try {
          ......
          // 调用了 decodeFromFetcher
          Resource<R> result = decodeFromFetcher(data, dataSource);
          ......
          return result;
        } finally {
        }
      }
    
      private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
          throws GlideException {
        // 1. 获取当前数据类的解析器 LoadPath
        LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
        // 2. 通过解析器来解析来解析数据
        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);
        // 2.1 根据数据类型获取一个数据重造器, 获取的数据为 InputStream, 因此它是一个 InputStreamRewinder 的实例
        DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
        try {
          // 2.2 将解析资源的任务转移到了 LoadPath.load 方法中
          return path.load( rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
        } finally {
          rewinder.cleanup();
        }
      }        
    }
    

    可以看到为了解析数据, 首先构建了一个LoadPath, 然后创建了一个InputStreamRewinder类型的 DataRewinder, 最终将数据解析的操作到了LoadPath.load方法中


    接下来看看这个LoadPath.load 做了哪些处理

    public class LoadPath<Data, ResourceType, Transcode> {
    
     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);
        } finally {
          ......
        }
      }
    
      private final List<? extends DecodePath<Data, ResourceType, Transcode>> decodePaths;
    
      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;
        // 遍历内部存储的 DecodePath 集合, 通过他们来解析数据
        for (int i = 0, size = decodePaths.size(); i < size; i++) {
          DecodePath<Data, ResourceType, Transcode> path = decodePaths.get(i);
          try {
            // 调用 DecodePath.decode 真正进行数据的解析
            result = path.decode(rewinder, width, height, options, decodeCallback);
          } catch (GlideException e) {
            ......
          }
          ......
        }
        return result;
      }
    
    }
    
    public class DecodePath<DataType, ResourceType, Transcode> {
    
      public Resource<Transcode> decode(DataRewinder<DataType> rewinder, int width, int height,
          @NonNull Options options, DecodeCallback<ResourceType> callback) throws GlideException {
        // 1\. 调用 decodeResource 将源数据解析成中间资源
        Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options);
        // 2\. 调用 DecodeCallback.onResourceDecoded 处理中间资源
        Resource<ResourceType> transformed = callback.onResourceDecoded(decoded);
        // 3\. 调用 ResourceTranscoder.transcode 将中间资源转为目标资源
        return transcoder.transcode(transformed, options);
      }
    
      private Resource<ResourceType> decodeResource(DataRewinder<DataType> rewinder, int width,
          int height, @NonNull Options options) throws GlideException {
        try {
          // 1.1 调用了 decodeResourceWithList
          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;
        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();
              // 1.2 调用 ResourceDecoder.decode 解析源数据
              result = decoder.decode(data, width, height, options);
            }
          } 
          ......
          if (result != null) {
            break;
          }
        }
        return result;
      }
    
    }
    

    可以看到数据解析的任务最重是通过DecodePath来执行的, 它内部有三个操作

    • 调用decodeResource将源数据解析成资源
      • 源数据: InputStream
      • 中间产物: Bitmap
    • 调用DecodeCallback.onResourceDecoded处理资源
    • 调用ResourceTranscoder.transcode将资源转为目标资源
      • 目标资源类型: Drawable

    解析源数据

    因为本次流程的源数据为InputStream因此它的解析器为StreamBitmapDecoder

    public class StreamBitmapDecoder implements ResourceDecoder<InputStream, Bitmap> {
    
      private final Downsampler downsampler;
    
      public Resource<Bitmap> decode(@NonNull InputStream source, int width, int height,
          @NonNull Options options)
          throws IOException {
        ......
        try {
          // 根据请求配置的数据, 对数据流进行采样压缩, 获取到一个 Resource<Bitmap>
          return downsampler.decode(invalidatingStream, width, height, options, callbacks);
        } finally {
          ......
        }
      }
    
    }
    

    可以看到它内部通过Downsampler.decode方法对数据流进行采样压缩, 来获取这个流的Bitmap

    • 这个采样的策略就是我们在构建Request时传入的, 其采样压缩的细节, 并不是我们本次关注的重点

    获取到了Resource之后, 又是如何处理这个资源的呢?


    资源的处理

    当我们将源数据解析成对应的资源之后, 便会调用DecodeCallback.onResourceDecoded处理资源

    class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
        Runnable,
        Comparable<DecodeJob<?>>,
        Poolable {
    
      private final class DecodeCallback<Z> implements DecodePath.DecodeCallback<Z> {
    
        @Override
        public Resource<Z> onResourceDecoded(@NonNull Resource<Z> decoded) {
          // 调用了外部类的 onResourceDecoded 方法
          return DecodeJob.this.onResourceDecoded(dataSource, decoded);
        }
    
      }
    
      private final DeferredEncodeManager<?> deferredEncodeManager = new DeferredEncodeManager<>();
    
      <Z> Resource<Z> onResourceDecoded(DataSource dataSource,
          @NonNull Resource<Z> decoded) {
        // 1. 获取数据资源的类型
        Class<Z> resourceSubClass = (Class<Z>) decoded.get().getClass();
        Transformation<Z> appliedTransformation = null;
        Resource<Z> transformed = decoded;
    
        // 2. 若非从资源磁盘缓存中获取的数据源, 则对资源进行 transformation 操作
        if (dataSource != DataSource.RESOURCE_DISK_CACHE) {
          appliedTransformation = decodeHelper.getTransformation(resourceSubClass);
          transformed = appliedTransformation.transform(glideContext, decoded, width, height);
        }
        ......
        // 3. 构建数据编码的策略
        final EncodeStrategy encodeStrategy;
        final ResourceEncoder<Z> encoder;
        if (decodeHelper.isResourceEncoderAvailable(transformed)) {
          encoder = decodeHelper.getResultEncoder(transformed);
          encodeStrategy = encoder.getEncodeStrategy(options);
        } else {
          encoder = null;
          encodeStrategy = EncodeStrategy.NONE;
        }
        // 4 根据编码策略, 构建缓存的 key
        Resource<Z> result = transformed;
        boolean isFromAlternateCacheKey = !decodeHelper.isSourceKey(currentSourceKey);
        if (diskCacheStrategy.isResourceCacheable(isFromAlternateCacheKey, dataSource,
            encodeStrategy)) {
          ......
          final Key key;
          switch (encodeStrategy) {
            case SOURCE:
              // 源数据的 key
              key = new DataCacheKey(currentSourceKey, signature);
              break;
            case TRANSFORMED:
              // 资源数据的 key
              key =
                  new ResourceCacheKey(......);
              break;
            default:
              throw new IllegalArgumentException("Unknown strategy: " + encodeStrategy);
          }
          // 5. 初始化编码管理者, 用于提交内存缓存
          LockedResource<Z> lockedResult = LockedResource.obtain(transformed);
          deferredEncodeManager.init(key, encoder, lockedResult);
          result = lockedResult;
        }
        // 返回 transform 之后的 bitmap
        return result;
      }
    
    }
    

    可以看到onResourceDecoded中, 主要是对中间资源做了如下的操作

    • 对资源进行transformed操作
      • 将资源转为目标效果, 如在构建request时, 设置的CenterCrop
    • 构建磁盘缓存的key

    好的, 这个方法执行结束之后, 这个资源就与我们期望的效果一致了, 接下来只需要将它转为目标格式就可以展示了


    将数据转为目标格式

    目标数据为Drawable, 因此它的转换器为BitmapDrawableTranscoder

    public class BitmapDrawableTranscoder implements ResourceTranscoder<Bitmap, BitmapDrawable> {
    
      private final Resources resources;
    
      @Nullable
      @Override
      public Resource<BitmapDrawable> transcode(@NonNull Resource<Bitmap> toTranscode,
          @NonNull Options options) {
        // 调用了 LazyBitmapDrawableResource.obtain 获取 Resource<BitmapDrawable> 的实例对象
        return LazyBitmapDrawableResource.obtain(resources, toTranscode);
      }
    
    }
    
    public final class LazyBitmapDrawableResource implements Resource<BitmapDrawable>,
        Initializable {
    
      public static Resource<BitmapDrawable> obtain(
          @NonNull Resources resources, @Nullable Resource<Bitmap> bitmapResource) {
        ......
        // 创建了一个 LazyBitmapDrawableResource
        return new LazyBitmapDrawableResource(resources, bitmapResource);
      }
    
      private LazyBitmapDrawableResource(@NonNull Resources resources,
          @NonNull Resource<Bitmap> bitmapResource) {
        this.resources = Preconditions.checkNotNull(resources);
        this.bitmapResource = Preconditions.checkNotNull(bitmapResource);
      }
    
      public BitmapDrawable get() {
        // Get 方法反回了一个 BitmapDrawable 对象
        return new BitmapDrawable(resources, bitmapResource.get());
      }
    
    }
    

    转化成目标数据也比较的简单, 它将我们解析到的bitmap存放到LazyBitmapDrawableResource内部, 然后外界通过get方法就可以获取到一个BitmapDrawable的对象了


    数据的展示

    class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
        Runnable,
        Comparable<DecodeJob<?>>,
        Poolable {
    
      private void decodeFromRetrievedData() {
        Resource<R> resource = null;
        ......// 解析 inputStream 获取资源 
        if (resource != null) {
          // 通知外界资源获取成功了
          notifyEncodeAndRelease(resource, currentDataSource);
        } else {
          ......
        }
      }
    
      private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
        ......
        // 1. 回调上层资源准备好了
        notifyComplete(result, dataSource);
        ......
        try {
          // 2. 将数据缓存到磁盘
          if (deferredEncodeManager.hasResourceToEncode()) {
            deferredEncodeManager.encode(diskCacheProvider, options);
          }
        } finally {
          ...
        }
      }
    
      private Callback<R> callback;
    
      private void notifyComplete(Resource<R> resource, DataSource dataSource) {
        ......
        // 1.1 从 DecodeJob 的构建中, 我们知道这个 Callback 是一 EngineJob
        callback.onResourceReady(resource, dataSource);
      }
    
    }
    

    可以看到DecodeJob.decodeFromRetrievedData中, 主要做了两个操作

    • 回调EngineJob.onResourceReady资源准备好了
    • 将数据缓存到磁盘

    磁盘缓存并非我们关注的终点, 这里我们看看EngineJob.onResourceReady中做了哪些处理

    class EngineJob<R> implements DecodeJob.Callback<R>,
        Poolable {
    
      @Override
      public void onResourceReady(Resource<R> resource, DataSource dataSource) {
        synchronized (this) {
          this.resource = resource;
          this.dataSource = dataSource;
        }
        notifyCallbacksOfResult();
      } 
    
      void notifyCallbacksOfResult() {
        ResourceCallbacksAndExecutors copy;
        Key localKey;
        EngineResource<?> localResource;
        synchronized (this) {
          ......
          engineResource = engineResourceFactory.build(resource, isCacheable);
          hasResource = true;
          copy = cbs.copy();
          incrementPendingCallbacks(copy.size() + 1);
    
          localKey = key;
          localResource = engineResource;
        }
        // 1. 通知上层 Engine 任务完成了
        listener.onEngineJobComplete(this, localKey, localResource);
        // 2. 回调给 ImageViewTarget 展示资源
        for (final ResourceCallbackAndExecutor entry : copy) {
          entry.executor.execute(new CallResourceReady(entry.cb));
        }
      }
    
    }
    
    

    EngineJob中也是有两步操作, 一个是通知上层任务完成了, 另一个是回调给ImageViewTarget展示资源


    我们先看看上层做了什么处理

    public class Engine implements EngineJobListener,
        MemoryCache.ResourceRemovedListener,
        EngineResource.ResourceListener {
    
      public synchronized void onEngineJobComplete(
          EngineJob<?> engineJob, Key key, EngineResource<?> resource) {
        if (resource != null) {
          // 将加载好的资源添加到内存缓存
          if (resource.isCacheable()) {
            activeResources.activate(key, resource);
          }
        }
        ......
      }
    
    }
    

    我们知道在请求发起前是Engine尝试通过内存缓存读, 结束之后再回到Engine添加内存缓存也不足为奇了

    接下来我们看看ImageViewTarget展示资源的过程

    public abstract class ImageViewTarget<Z> extends ViewTarget<ImageView, Z>
        implements Transition.ViewAdapter {
    
      public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
        // 处理一些 transition 变化, 在构建 Request 时有分析过, 这里不赘述其实现细节了
        if (transition == null || !transition.transition(resource, this)) {
          setResourceInternal(resource);
        } else {
          ......
        }
      }
    
      private void setResourceInternal(@Nullable Z resource) {
        // 调用了 setResource
        setResource(resource);
        ......
      }
    
    }
    
    public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
    
      protected void setResource(@Nullable Drawable resource) {
        // 呈现到 View 上
        view.setImageDrawable(resource);
      }  
    
    }
    

    ImageViewTarget调用了子类重写的setResource方法, 将数据填充进去, 至此一次Glide图像加载就完成了

    总结

    通过一次流程分析我们得知, 整个Glide图片加载主要有如下几步

    • 请求管理器的构建
      • 一个Context对应一个RequestManager
    • 请求的构建
      • 请求的宽高、采样的方式、transform变化...
    • 通过请求获取资源
      • Engine从内存缓存中查找
        • ActiveResources缓存中查找
        • Cache缓存中查找
      • 内存缓存不存在, 则构建任务执行
        • 构建一个EngineJob描述一个请求任务, 任务类型为DecodeJob
          • DecodeJobdiskCache中查找
          • diskCache不存在, 则通过网络请求, 获取数据源
          • 通过Downsampler解析源数据并进行采样压缩获取Bitmap
          • Bitmap进行transform处理
            • 构建磁盘缓存的key
          • transform之后的Bitmap转为Resource回传给上层
            • DecodeJob进行磁盘缓存
      • Engine对资源进行内存缓存
    • 传递给View进行展示

    Glide的源码还是真的有点复杂,这还只是最简单的流程,都给我看蒙了,可想而知他内部代码逻辑有多复杂。

    相关文章

      网友评论

        本文标题:Glide图片加载三步曲源码解析

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