Glide 从with到into

355 阅读5分钟

Glide 4.11.0 版本,后面版本有小的改动;

.with(this)

逻辑流程

with 主要作用是绑定View所在的 Activity 的生命周期,如果主动设置或者设置子线程中会使用到application 的生命周期

image.png 作用区域: 主线程主要在:Activity Fragment中,子线程主要石apppliacation 的作用域

代码流程

image.png

RequestManager.get 获取主线程 生成一个空白的SupportRequestManagerFragment ,为了节省内存,防止用户异常调用, SupportRequestManagerFragment 保证了唯一性,并进行了双重认证;

  @NonNull
  private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
    SupportRequestManagerFragment current =
        (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);// 第一层认证 
    if (current == null) {
      current = pendingSupportRequestManagerFragments.get(fm);// 第二层认证
      if (current == null) {
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingSupportRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();// handLer 运行
      }
    }
    return current;
  }

第一层认证FragmentManager 的管理来判断 是否已经存在,在添加fragment 的时候有个细节,由于FragmentManager 事物基于handler 并且不是及时执行,需要 handler.obtainMessage 让handler 运转起来; 第二层的检测 是通过 map 集合判断唯一性

Fragment绑定 Activity/Fragment的 生命周期,然后通知到RequestManager 下发到Set lifecycleListeners 所有需要生命周期的下属逻辑

.load(urlImg)

对要加载的图片资源的寻找

逻辑流程

image.png 资源配置类型决定了后续BUildData 的类型,

代码流程

image.png

  1. asDrawable().load(string) 图片请求器来加载
public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
  }
  1. RequestBuilde 构建
  @Nullable private Object model;// 资源
   private boolean isModelSet; // url 是否就位
   private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }

.into(imageView)

逻辑流程

image.png

  1. 首先会对活动缓存进行检测,如果有就直接返回;
  2. 活动缓存没有,会查找内存缓存,内存存在 内存剪切到 活缓存
  3. 内存缓存不存在,会查找本地磁盘缓存一样是Lru;
  4. 内存缓存不存在会使用,网络加载,加载到数据,存储到本地缓存,copy 到 活动缓存 资源完全加载成功
  5. 在View Destory 活动消失,活动缓存会剪切到到内存缓存

代码流程

image.png

第一点:为 target buildRequest 构建一个 Glide request 请求;

第二点:将构建出来的 Request 交于 RequestManager 来执行;

  private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    Preconditions.checkNotNull(target);
    //这里的 isModelSet 是在 load 的时候赋值为 true 的,所以不会抛异常
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }
		//为这个 http://xxx.png 生成一个 Glide request 请求
    Request request = buildRequest(target, targetListener, options, callbackExecutor);
		//相当于拿到上一个请求
    Request previous = target.getRequest();
    //下面的几行说明是否与上一个请求冲突,一般不用管 直接看下面 else 判断
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      request.recycle();
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        previous.begin();
      }
      return target;
    }
		//清理掉目标请求管理
    requestManager.clear(target);
    //重新为目标设置一个 Glide request 请求
    target.setRequest(request);
    //最后是调用 RequestManager 的 track 来执行目标的 Glide request 请求
    requestManager.track(target, request);

    return target;
  }
  • 2.onSizeReady 资源准备,没有的话new job 去执行
public synchronized void onSizeReady(int width, int height) {
    stateVerifier.throwIfRecycled();
    ....//都是一些初始化状态,配置属性,我们不用管。
 
    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);
  }
  • 3.资源准备核心代码SingleRequest begin load
  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;
  }

  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);
      }
    }
  • 4 DecodeJob run 决定了资源加载的执行器
  private void runWrapped() {
    switch (runReason) {
      case INITIALIZE:
        //获取资源状态
        stage = getNextStage(Stage.INITIALIZE);
        //根据当前资源状态,获取资源执行器
        currentGenerator = getNextGenerator();
        //执行
        runGenerators();
        break;
      ...
    }
  }
private Stage getNextStage(Stage current) {
    switch (current) {
      case INITIALIZE:
        //如果外部调用配置了资源缓存策略,那么返回 Stage.RESOURCE_CACHE
       	//否则继续调用 Stage.RESOURCE_CACHE 执行。
        return diskCacheStrategy.decodeCachedResource()
            ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
      case RESOURCE_CACHE:
        //如果外部配置了源数据缓存,那么返回 Stage.DATA_CACHE
        //否则继续调用 getNextStage(Stage.DATA_CACHE)
        return diskCacheStrategy.decodeCachedData()
            ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
      case DATA_CACHE:
        //如果只能从缓存中获取数据,则直接返回 FINISHED,否则,返回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);
    }
  }

从上述代码中可以知道,我们配置任何配置,所以执行器为 SourceGenerator

  • 5 SourceGenerator 加载资源,Glide with 配置为一个网路加载, modelLoader.buildLoadData 添加的为 HttpGlideUrlLoader 加载器
List<LoadData<?>> getLoadData() {
    if (!isLoadDataSet) {
      isLoadDataSet = true;
      loadData.clear(); 
      //从 Glide 注册的 Model 来获取加载器(注册是在 Glide 初始化的时候通过 registry
       // .append()添加的)
      List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);

      for (int i = 0, size = modelLoaders.size(); i < size; i++) {
        ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
        LoadData<?> current =
          //开始构建加载器
            modelLoader.buildLoadData(model, width, height, options);
        if (current != null) {
          loadData.add(current);
        }
      }
    }
    return loadData;
  }
  • 6 notifyEncodeAndRelease
private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
    ...
	//通知调用层数据已经装备好了
    notifyComplete(result, dataSource);

    stage = Stage.ENCODE;
    try {
      //这里就是将资源磁盘缓存
      if (deferredEncodeManager.hasResourceToEncode()) {
        deferredEncodeManager.encode(diskCacheProvider, options);
      }
    } finally {
     ...
    }
	//完成
    onEncodeComplete();
  }

  private void notifyComplete(Resource<R> resource, DataSource dataSource) {
    setNotifiedOrThrow();
    // 在 DecodeJob 的构建中, 我们知道这个 Callback 是 EngineJob
    callback.onResourceReady(resource, dataSource);
  }
}

第一个处理:解析返回回来的资源。 onEncodeComplete();

第二个处理:拿到解析的资源,如果配置了本地缓存,就缓存到磁盘。 deferredEncodeManager.encode

第三个处理:通知上层资源准备就绪,可以使用了。allback.onResourceReady