美文网首页
Glide源码详解

Glide源码详解

作者: kjy_112233 | 来源:发表于2019-01-25 11:21 被阅读0次

    一、源码解析

    (1)Glide.with(this):初始化、绑定生命周期、获得RequestManager实例

    • with方法可以接受Context、Activity、FragmentActivity、Fragment、View不同的类型,返回值都是RequestManager对象。
      @NonNull
      public static RequestManager with(@NonNull FragmentActivity activity) {
        return getRetriever(activity).get(activity);
      }
    
      @NonNull
      private static RequestManagerRetriever getRetriever(@Nullable Context context) {
        //code..
        //创建一个Glide实例,调用getRequestManagerRetriever返回了一个RequestManagerRetriever实例
        return Glide.get(context).getRequestManagerRetriever();
      }
    
      //双重加锁的单例模式保证Glide对象的唯一性
      @NonNull
      public static Glide get(@NonNull Context context) {
        if (glide == null) {
          GeneratedAppGlideModule annotationGeneratedModule =
              getAnnotationGeneratedGlideModules(context.getApplicationContext());
          synchronized (Glide.class) {
            if (glide == null) {
              checkAndInitializeGlide(context, annotationGeneratedModule);
            }
          }
        }
        return glide;
      }
    
      @GuardedBy("Glide.class")
      private static void checkAndInitializeGlide(
          @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
        //防止无限递归操作
        if (isInitializing) {
          throw new IllegalStateException(
              "You cannot call Glide.get() in registerComponents(),"
                  + " use the provided Glide instance instead");
        }
        isInitializing = true;
        initializeGlide(context, generatedAppGlideModule);
        isInitializing = false;
      }
    
      @GuardedBy("Glide.class")
      private static void initializeGlide(
          @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
        //创建GlideBuilder对象
        initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
      }
    
      @GuardedBy("Glide.class")
      @SuppressWarnings("deprecation")
      private static void initializeGlide(
          @NonNull Context context,
          @NonNull GlideBuilder builder,
          @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
        //code...
        builder.setRequestManagerFactory(factory);
        for (com.bumptech.glide.module.GlideModule module : manifestModules) {
          module.applyOptions(applicationContext, builder);
        }
        if (annotationGeneratedModule != null) {
          annotationGeneratedModule.applyOptions(applicationContext, builder);
        }
        //调用build方法来完成Glide对象的创建
        Glide glide = builder.build(applicationContext);
        //code..
        applicationContext.registerComponentCallbacks(glide);
        Glide.glide = glide;
      }
    
    • RequestManagerRetriever.get方法
      @NonNull
      public RequestManager get(@NonNull FragmentActivity activity) {
        //判断是否在子线程执行
        if (Util.isOnBackgroundThread()) {
          return get(activity.getApplicationContext());
        } else {
          assertNotDestroyed(activity);
          FragmentManager fm = activity.getSupportFragmentManager();
          return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
        }
      }
    
      @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)) {//主线程或非Application
          if (context instanceof FragmentActivity) {
            return get((FragmentActivity) context);
          } else if (context instanceof Activity) {
            return get((Activity) context);
          } else if (context instanceof ContextWrapper
              && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
            return get(((ContextWrapper) context).getBaseContext());
          }
        }
        return getApplicationManager(context);//Application或者子线程
      }
    
      @NonNull
      private RequestManager supportFragmentGet(
          @NonNull Context context,
          @NonNull FragmentManager fm,
          @Nullable Fragment parentHint,
          boolean isParentVisible) {
        SupportRequestManagerFragment current =
            getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context);
          requestManager =
              factory.build(
                  glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
          current.setRequestManager(requestManager);
        }
        return requestManager;
      }
    
      @Deprecated
      @NonNull
      private RequestManager fragmentGet(
          @NonNull Context context,
          @NonNull android.app.FragmentManager fm,
          @Nullable android.app.Fragment parentHint,
          boolean isParentVisible) {
        //获取空Fragment,利用Fragment的生命周期绑定Glide请求的生命周期
        RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
        //获取requestManager
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
          Glide glide = Glide.get(context);
          //重新构建一个requestManager,
          requestManager =
              factory.build(
                  glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
          current.setRequestManager(requestManager);
        }
        return requestManager;
      }
    
    • 两条线路的主要区别在于传进去的Lifecycle参数不一样,Application传进去的是ApplicationLifecycle,而Activity、Fragment等传进去的是ActivityFragmentLifecycle。

    (2)Glide.with(this).load(imageUrl):创建RequestBuilder对象,资源参数、结果类型都赋值给这个RequestBuilder实例并返回

    • load方法可以接受Bitmap、Drawable、String、Uri、File、Integer、URL、byte[]、Object不同类型,返回值都是RequestBuilder<Drawable>。
      public RequestBuilder<Drawable> load(@Nullable String string) {
        return asDrawable().load(string);
      }
    
      @NonNull
      @CheckResult
      public RequestBuilder<Drawable> asDrawable() {
        return as(Drawable.class);
      }
    
      @NonNull
      @CheckResult
      public <ResourceType> RequestBuilder<ResourceType> as(
          @NonNull Class<ResourceType> resourceClass) {
        //将结果类型赋值给RequestBuilder
        return new RequestBuilder<>(glide, this, resourceClass, context);
      }
    
      @NonNull
      @Override
      @CheckResult
      public RequestBuilder<TranscodeType> load(@Nullable String string) {
        return loadGeneric(string);
      }
    
      //将资源参数赋值给RequestBuilder
      @NonNull
      private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
        this.model = model;
        isModelSet = true;
        return this;
      }
    

    (3)Glide.with(this).load(imageUrl).into(imageView)

      @NonNull
      public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
        Util.assertMainThread();
        Preconditions.checkNotNull(view);
        //通过apply传进来的实例
        BaseRequestOptions<?> requestOptions = this;
        //判断是否设置ScaleType类型
        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.
          }
        }
    
        return into(
            glideContext.buildImageViewTarget(view, transcodeClass),
            /*targetListener=*/ null,
            requestOptions,
            Executors.mainThreadExecutor());
      }
    
      //调用ImageViewTargetFactory来生成对应的ViewTarget:ImageView与返回结果类型X
      @NonNull
      public <X> ViewTarget<ImageView, X> buildImageViewTarget(
          @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
        return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
      }
    
      //通过Z区分两种返回结果Bitmap和Drawable
      @NonNull
      @SuppressWarnings("unchecked")
      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)) {
          return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
        } else {
          throw new IllegalArgumentException(
              "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
        }
      }
    
    • 查看into(Target,RequestListener,RequestOptions)方法
      private <Y extends Target<TranscodeType>> Y into(
          @NonNull Y target,
          @Nullable RequestListener<TranscodeType> targetListener,
          BaseRequestOptions<?> options,
          Executor callbackExecutor) {
        //判断target(返回结果类型)是否为null
        Preconditions.checkNotNull(target);
        //判断load中赋值的资源参数是否为null
        if (!isModelSet) {
          throw new IllegalArgumentException("You must call #load() before calling #into()");
        }
        //创建一个request实例
        Request request = buildRequest(target, targetListener, options, callbackExecutor);
        //通过target获取target中的Request
        Request previous = target.getRequest();
        //两个Request对象的参数是否完全一致
        //判断当前Glide的缓存功能是否打开
        if (request.isEquivalentTo(previous)
            && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
          if (!Preconditions.checkNotNull(previous).isRunning()) {
            previous.begin();
          }
          return target;
        }
    
        requestManager.clear(target);
        target.setRequest(request);
        requestManager.track(target, request);
    
        return target;
      }
    
      @Override
      public void begin() {
        synchronized (requestLock) {
          assertNotCallingCallbacks();
          stateVerifier.throwIfRecycled();
          startTime = LogTime.getLogTime();
          //判断要加载的资源是否为空
          if (model == null) {
            if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
              width = overrideWidth;
              height = overrideHeight;
            }
            int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
            //url为空,直接返回Fail设置的占位图
            onLoadFailed(new GlideException("Received null model"), logLevel);
            return;
          }
    
          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());
          }
          if (IS_VERBOSE_LOGGABLE) {
            logV("finished run method in " + LogTime.getElapsedMillis(startTime));
          }
        }
      }
    
      //通过Engine.load()方法去加载,请求完成后通过onResourceReady()方法回调ImageView
      @Override
      public void onSizeReady(int width, int height) {
          //code...
          loadStatus =
              engine.load(
                  //code..
                  this,//倒数第二个参数回调
                  callbackExecutor);
          //code...
      }
    
      public <R> LoadStatus load(
          //code...
          ResourceCallback cb,
          Executor callbackExecutor) {
        long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;
        //创建EngineKey实例,关联model、view宽高等属性;key用来指定缓存地址、从缓存中查询资源
        EngineKey key =
            keyFactory.buildKey(
                model,
                signature,
                width,
                height,
                transformations,
                resourceClass,
                transcodeClass,
                options);
    
        EngineResource<?> memoryResource;
        synchronized (this) {
          //读取缓存资源
          memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
    
          if (memoryResource == null) {
             //没有缓存数据,发起一个新的请求
            return waitForExistingOrStartNewJob(
                glideContext,
                model,
                signature,
                width,
                height,
                resourceClass,
                transcodeClass,
                priority,
                diskCacheStrategy,
                transformations,
                isTransformationRequired,
                isScaleOnlyOrNoTransform,
                options,
                isMemoryCacheable,
                useUnlimitedSourceExecutorPool,
                useAnimationPool,
                onlyRetrieveFromCache,
                cb,
                callbackExecutor,
                key,
                startTime);
          }
        }
        //回调ImageView
        cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
        return null;
      }
    
      private EngineResource<?> loadFromMemory(
          EngineKey key, boolean isMemoryCacheable, long startTime) {
        if (!isMemoryCacheable) {
          return null;
        }
        //读取缓存,从活动资源加载
        EngineResource<?> active = loadFromActiveResources(key);
        if (active != null) {
          if (VERBOSE_IS_LOGGABLE) {
            logWithTimeAndKey("Loaded resource from active resources", startTime, key);
          }
          return active;
        }
        //读取缓存,从内存中加载
        EngineResource<?> cached = loadFromCache(key);
        if (cached != null) {
          if (VERBOSE_IS_LOGGABLE) {
            logWithTimeAndKey("Loaded resource from cache", startTime, key);
          }
          return cached;
        }
        return null;
      }
    
      private <R> LoadStatus waitForExistingOrStartNewJob(
          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,
          EngineKey key,
          long startTime) {
    
        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对象负责开启线程去加载资源,并且加载得资源后转换到主线程并进行回调
        EngineJob<R> engineJob =
            engineJobFactory.build(
                key,
                isMemoryCacheable,
                useUnlimitedSourceExecutorPool,
                useAnimationPool,
                onlyRetrieveFromCache);
    
        //DecodeJob是真正的执行者,它就是去网络加载资源的地方
        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);
        //cb添加到engineJob.addCallback()中
        engineJob.addCallback(cb, callbackExecutor);
        //start方法来开启线程
        engineJob.start(decodeJob);
    
        if (VERBOSE_IS_LOGGABLE) {
          logWithTimeAndKey("Started new load", startTime, key);
        }
        return new LoadStatus(cb, engineJob);
      }
    
    • 获取数据:首先Glide会根据当前用户是否有通过override来重新指定加载的宽高,有的话就使用指定的宽高,没有的话就会读取ImageView的宽高,然后调用了Engine的load方法,建立了两个关键的对象:EngineJob和DecodeJob,EngineJob负责调度线程,DecodeJob负责请求解析数据,DecodeJob会生成一个DataFetcherGenerator,它负责生成对应的DataFetcher(这里的对应是Glide初始化的时候就已经匹配好了,什么资源需要对应什么解析器),找到解析器之后会调用其具体的loadData方法,获取图片数据。
    • 解析数据:拿到数据之后就先通过EngineJob切换线程,保证在同一线程下,然后通过ResourceDecoder的decode接口,将我们的数据转换为ImageView可以展示的类型(比如Bitmap、Drawable)。
    • 结果展示:将其回调回去,并通过EngineJob将线程切换为主线程,为展示做准备,结果会一直回调到Request,然后由Request通知Target可以准备展示了,最后Target收到通知拿到数据将其展示出来。

    相关文章

      网友评论

          本文标题:Glide源码详解

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