Glide 4.7.1源码分析--启动加载 into(view)

Glide源码分析 – 启动图片加载流程

// 在 RequestBuilder.into()之前必须调用load()系列方法,设置model
// 重载的一系列into()方法最终都调用
/* private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @NonNull RequestOptions options) 
      */
 Glide.with(context)
                .load(url)
                .apply(requestOptions)
                .into(iv);

在这里分析 参数是 imageView的 RequestBuilder.into(imageview)
① public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view)

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

    RequestOptions requestOptions = this.requestOptions;
    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:
      }
    }
    // glideContext.buildImageViewTarget(view, transcodeClass)
    // 创建返回目标,根据
    //Glide.with(context).asBitmap()
//    Glide.with(context).asDrawable() 返回
    /*
   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)");
    }
  }
  */
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions);
  }

②进入 public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view)

private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @NonNull RequestOptions options) {
    Util.assertMainThread();
    Preconditions.checkNotNull(target);
    // 这里表明 调用 into()之前必须调用load()设置model
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }
    options = options.autoClone();
    // 创建本次请求对象,跟踪发现最终调用SingleRequest.obtain()
    // 返回 SingleRequest对象
    Request request = buildRequest(target, targetListener, options);
    // 获取上次请求
    Request previous = target.getRequest();
//如果本次请求与上次请求相同,并且未设置跳过内存缓存
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
        // 回收本次请求
      request.recycle();
      //如果 previous 已经请求完毕,会返回false
      if (!Preconditions.checkNotNull(previous).isRunning()) {
      //使用 previous 去请求,如果有缓存会使用缓存
        previous.begin();
      }
      return target;
    }
   //这里会回收 target 的上次请求对象
	requestManager.clear(target);
	//给 target 设置本次请求的 request
	target.setRequest(request);
	//把请求塞入队列,根据页面是否在前台,来处理请求
	requestManager.track(target, request);
    return target;
  }

② 开始请求 Request.begin()

public void begin() {
    ...
    ...
    // 尺寸有效
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
    // 真正请求加载图片
      onSizeReady(overrideWidth, overrideHeight);
    } else {
    // 获取尺寸,尺寸有效会回调  onSizeReady(overrideWidth, overrideHeight)
      target.getSize(this);
    }
  }
// 这里开始加载图片
 public void onSizeReady(int width, int height) {
   ...
   // 引擎类开始加载
    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);
  }

③ Engine 开始执行图片加载逻辑

public class Engine implements EngineJobListener, ... {
	
	/* 弱引用实现 活动缓存
	 * activeResources 是Glide通过引用计数实现 Bitmap复用的关键
	 */
	private final ActiveResources activeResources;
	
	/* 内存缓存 LruCache 实现
	 * LruCache 内部是一个 LinkedHashMap,使用LRU 最近最少访问算法,淘汰缓存
	 */
	private final MemoryCache cache;
	
	private final LazyDiskCacheProvider diskCacheProvider;//磁盘缓存
	
	public <R> LoadStatus load(...) {
		//到这里还是主线程
		Util.assertMainThread();
		/* 根据请求信息(包括load(model)方法的参数、图片宽高等),构建 key
		 * 这个key,也是用于 memoryCache  diskCache 的key
		 */
		EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
			resourceClass, transcodeClass, options);
		
		//从 活动缓存 activeResources 去拿图片
		EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
		if (active != null) {
			//从活动缓存中找到图片后,回调 onResourceReady() 方法	
			cb.onResourceReady(active, DataSource.MEMORY_CACHE);
			...
			return null;
		}
		/* 活动缓存 activeResources 中没找到图片
		 * 去内存缓存 cache 中获取图片
		 */
		EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
		if (cached != null) {
			//从内存缓存中找到图片后,回调 onResourceReady() 方法	
			cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
			...
			return null;
		}
		//根据key 获取 EngineJob
		EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
		if (current != null) {
			current.addCallback(cb);
			...
			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);
		//根据key 缓存 EngineJob
		jobs.put(key, engineJob);
		engineJob.addCallback(cb);
		
		engineJob.start(decodeJob);
		...
		return new LoadStatus(cb, engineJob);
	}			
}
发布了38 篇原创文章 · 获赞 8 · 访问量 8630
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章