Glide源码执行流程深入分析

一直想写关于Glide的文章,但是始终没写。Glide非常强大,它背后帮我们执行了非常多的逻辑,使我们调用起来非常简单。最近又深入学习了它的代码,趁此有机会记录下来,其实之前已经看过郭神的关于Glide的分析,写得非常详细,但是是基于3.x的,而我们最近使用都是4.x的,部分执行流程有所变化。所以还是打算自己整理一遍头绪,方便以后回顾,但是不会写得太详细,毕竟流程也非常多,只需要把关键点记录下来,然后对着源代码跟踪就可以了。


1、Glide初始化

Glide是一个单例对象,里面的很多模块都是提前在它的构造方法中完成的,并且会注册到一个容器中,只会注册一次,而在我们从不同的地方去加载图片的时候会从容器去获取加载图片的模块,可以说设计得非常高级。

//返回单例对象
public static Glide get(@NonNull Context context) {
 if (glide == null) {
   synchronized (Glide.class) {
     if (glide == null) {
     //初始化Glide
       checkAndInitializeGlide(context);
     }
   }
 }

 return glide;
}

glide的创建是在GlideBuilder中

@NonNull
Glide build(@NonNull Context context) {
//相关对象初始化,然后传到Glide构造方法中
...

  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptions.lock(),
      defaultTransitionOptions,
      defaultRequestListeners,
      isLoggingRequestOriginsEnabled);
}

在GlideBuilder创建glide之前会先初始化它的构造方法所需要的对象,当然我们也可以自定义,接着跟踪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) {
  ...
    registry = new Registry();
    registry.register(new DefaultImageHeaderParser());
 
    registry
 ...
        .append(String.class, InputStream.class, new StringLoader.StreamFactory())
        .append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
  	...
        .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
    ...
...
  }

在它的构造方法主要就是将不同的模块注册到Register对象中,我们看下主要的模块注册到了哪里

//MultiModelLoaderFactory
  private <Model, Data> void add(
      @NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass,
      @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory,
      boolean append) {
    Entry<Model, Data> entry = new Entry<>(modelClass, dataClass, factory);
    entries.add(append ? entries.size() : 0, entry);
  }

最后注册到了entries中,它是一个ArrayList,当然还有其它模块注册在别的地方,这里就不过多解释。


2、with

Glide的with方法有多个重载方法,但是里面都会调用这个方法

@NonNull
 private static RequestManagerRetriever getRetriever(@Nullable Context context) {
 ...
   return Glide.get(context).getRequestManagerRetriever();
 }

Glide.get获取的是glide的单例对象,而getRequestManagerRetriever方法获取的是requestManagerRetriever,它是Glide的全局对象,返回这个对象之后,接着会调用它的get方法,它会根据with传入的不同对象调用它的不同重载方法,拿传入Activity举例

  @NonNull
public RequestManager get(@NonNull Activity activity) {
//1是否在子线程
  if (Util.isOnBackgroundThread()) {
    return get(activity.getApplicationContext());
  } else {
//2
    assertNotDestroyed(activity);
    android.app.FragmentManager fm = activity.getFragmentManager();
    return fragmentGet(
        activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
  }
}

看注释2处,先获取FragmentManager,接着会调用fragmentGet方法

private RequestManager fragmentGet(@NonNull Context context,
    @NonNull android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint,
    boolean isParentVisible) {
   //1
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
  //2
  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;
}

在注释1处会获取一个Fragment

  @NonNull
private RequestManagerFragment getRequestManagerFragment(
    @NonNull final android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint,
    boolean isParentVisible) {
  RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
  if (current == null) {
    current = pendingRequestManagerFragments.get(fm);
    if (current == null) {
      current = new RequestManagerFragment();
      current.setParentFragmentHint(parentHint);
      if (isParentVisible) {
        current.getGlideLifecycle().onStart();
      }
      pendingRequestManagerFragments.put(fm, current);
      fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
      handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
    }
  }
  return current;
}

在这里会创建一个Fragment和当前Activity进行绑定,它里面有一个lifecycle会根据Fragment的生命周期变化,进行回调

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

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

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

到了这里总结下,就是在Activity中会创建一个看不见的Fragment和当前Activity进行绑定,当Activity生命周期变化时候,Fragment可以回调到,然后在它的生命周期方法中回调lifecycle的回调方法。

最后再回到fragmentGet的方法中,在注释2处会创建RequestManager,然后返回出去。


3、load

RequestManager的load方法也有很多重载方法,这里就拿我们最常用的举例

public RequestBuilder<Drawable> load(@Nullable String string) {
  return asDrawable().load(string);
}

这里的asDrawable()会调用到as()方法

  public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }

参数resourceClass为Drawable.class,传入RequestBuilder构造方法,后面会有用,然后接着调用RequestBuilder的load方法

public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}

@NonNull
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
  this.model = model;
  isModelSet = true;
  return this;
}

从这里可以看到load是做了赋值操作


4. into

这里才是整个图片加载的核心部分,也是最复杂的地方,下面慢慢道来

public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
//省略图片scaleType转换部分
...

 return into(
 //1
     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) {
...
//2
	 Request request = buildRequest(target, targetListener, options, callbackExecutor);
	
	...
//3
	 target.setRequest(request);
//4
	 requestManager.track(target, request);
	
	 return target;
}

注释1处传入transcodeClass然后构造Target

//ImageViewTargetFactory
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)");
  }
}

transcodeClass刚刚提过就是Drawable.class,这里就会创建DrawableImageViewTarget

注释2处构造一个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) {
      //构造了一个SingleRequest
    return SingleRequest.obtain(
        context,
        glideContext,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(),
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
  }

再看注释3处

  private void setTag(@Nullable Object tag) {
    if (tagId == null) {
      isTagUsedAtLeastOnce = true;
      view.setTag(tag);
    } else {
      view.setTag(tagId, tag);
    }
  }

会将request和view进行绑定

注释4处执行这个request

public void runRequest(@NonNull Request request) {
  requests.add(request);
  if (!isPaused) {
    request.begin();  //1
  } else {
    request.clear();
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      Log.v(TAG, "Paused, delaying request");
    }
    pendingRequests.add(request);
  }
}

在注释1处,调用begin()执行刚刚创建的Request

  @Override
  public synchronized void begin() {
  ...
  //1
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } else {
 //2   
      target.getSize(this);
    }

  ...
  }

注释1处会检测overrideWidth和overrideHeight是否合法,合法就调用onSizeReady,否则在注释2处去获取目标target的size,获取之后也会调用onSizeReady

public synchronized 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,
          callbackExecutor);

 ...
}

在这个方法中会调用Engine的load方法,跟踪进去

  public synchronized <R> LoadStatus load(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class<?> resourceClass,
      Class<R> transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map<Class<?>, Transformation<?>> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      Options options,
      boolean isMemoryCacheable,
      boolean useUnlimitedSourceExecutorPool,
      boolean useAnimationPool,
      boolean onlyRetrieveFromCache,
      ResourceCallback cb,
      Executor callbackExecutor) {
    long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;
...

    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);  //1

 ...
    return new LoadStatus(cb, engineJob);
  }

注意这里省略了Glide的内存缓存部分,因为这是一大头,具体可以看这里学习

这段代码会创建EngineJob和DecodeJob,前者封装了Glide的线程池,后者是一个Runable,在注释1处就是通过线程池执行这个Runable将线程切换到子线程

  public void run() {
 ...
    try {
      if (isCancelled) {
        notifyFailed();
        return;
      }
      runWrapped();  //1
    } catch (CallbackException e) {
      // If a callback not controlled by Glide throws an exception, we should avoid the Glide
      // specific debug logic below.
      throw e;
    } catch (Throwable t) {
     ...
    } finally {
   ...
    }
  }

代码都在注释1的方法内

private void runWrapped() {
  switch (runReason) {
    case INITIALIZE:
      //1	
      stage = getNextStage(Stage.INITIALIZE); 
      currentGenerator = getNextGenerator();
      runGenerators();
      break;
    case SWITCH_TO_SOURCE_SERVICE:
      runGenerators();
      break;
    case DECODE_DATA:
      decodeFromRetrievedData();
      break;
    default:
      throw new IllegalStateException("Unrecognized run reason: " + runReason);
  }
}

根据不同的runReason执行不同的逻辑,第一次进来为INITIALIZE,执行注释1,getNextStage里面会通过递归调用获取不同的state

private Stage getNextStage(Stage current) {
  switch (current) {
    case INITIALIZE:
      return diskCacheStrategy.decodeCachedResource()
          ? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
    case RESOURCE_CACHE:
      return diskCacheStrategy.decodeCachedData()
          ? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
    case DATA_CACHE:
      // Skip loading from source if the user opted to only retrieve the resource from cache.
      return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
    case SOURCE:
    case FINISHED:
      return Stage.FINISHED;
    default:
      throw new IllegalArgumentException("Unrecognized stage: " + current);
  }
}

再看getNextGenerator

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

会根据不同的state返回不同的Generator,而我们最后去请求网络的部分是SourceGenerator,再来看怎么执行的

  private void runGenerators() {
    currentThread = Thread.currentThread();
    startFetchTime = LogTime.getLogTime();
    boolean isStarted = false;
    while (!isCancelled && currentGenerator != null
    //1
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();

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

这个while循环里面会去寻找合适的Generator,当然最后都找不到就会在注释1执行SourceGenerator的startNext()

@Override
public boolean startNext() {
  if (dataToCache != null) {
    Object data = dataToCache;
    dataToCache = null;
    cacheData(data);
  }

  if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
    return true;
  }
  sourceCacheGenerator = null;
//1
  loadData = null;
  boolean started = false;
  
  while (!started && hasNextModelLoader()) {
    loadData = helper.getLoadData().get(loadDataListIndex++);
    if (loadData != null
        && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
        || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
      started = true;
      
      loadData.fetcher.loadData(helper.getPriority(), this);  //2
    }
  }
  return started;
}

在注释1之前是缓存部分,注释1之后是到之前Glide初始化注册的模块里面找能处理的模块

synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
  try {
    List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
    for (Entry<?, ?> entry : entries) {
      if (alreadyUsedEntries.contains(entry)) {
        continue;
      }
      if (entry.handles(modelClass)) {
        alreadyUsedEntries.add(entry);
        loaders.add(this.<Model, Object>build(entry));
        alreadyUsedEntries.remove(entry);
      }
    }
    return loaders;
  } catch (Throwable t) {
    alreadyUsedEntries.clear();
    throw t;
  }
}

最后在注释2处loadData.fetcher是MultiModelLoader,这个也不多做解释了,这个是可以调试的

往下面走,会调用它的loadData,它里面会调用HttpUrlFetcher的loadData

@Override
public void loadData(@NonNull Priority priority,
    @NonNull DataCallback<? super InputStream> callback) {
  long startTime = LogTime.getLogTime();
  try {
    InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders()); //1
    callback.onDataReady(result); //2
  } catch (IOException e) {
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(TAG, "Failed to load data for url", e);
    }
    callback.onLoadFailed(e);
  } finally {
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      Log.v(TAG, "Finished http url fetcher fetch in " + LogTime.getElapsedMillis(startTime));
    }
  }
}

在注释1处根据url去获取对应的流

private InputStream loadDataWithRedirects(URL url, int redirects, URL lastUrl,
    Map<String, String> headers) throws IOException {
...

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

  // Stop the urlConnection instance of HttpUrlConnection from following redirects so that
  // redirects will be handled by recursive calls to this method, loadDataWithRedirects.
  urlConnection.setInstanceFollowRedirects(false);

  // Connect explicitly to avoid errors in decoders if connection fails.
  urlConnection.connect();
  // Set the stream so that it's closed in cleanup to avoid resource leaks. See #2352.
  stream = urlConnection.getInputStream();
  if (isCancelled) {
    return null;
  }
  final int statusCode = urlConnection.getResponseCode();
  if (isHttpOk(statusCode)) {
    return getStreamForSuccessfulRequest(urlConnection);
  }
  ...
}

这个是通过最原生的HttpURLConnection去请求网络,拿到InputStream,当然这个模块是可以替换的,可以去自行谷歌

拿到InputStream之后在注释2处通过callback回调出去,看下怎么处理的

//SourceGenerator
@Override
 public void onDataReady(Object data) {
   DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
   if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
     dataToCache = data; //1
     // We might be being called back on someone else's thread. Before doing anything, we should
     // reschedule to get back onto Glide's thread.
     cb.reschedule();  //2
   } else {
     cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher,
         loadData.fetcher.getDataSource(), originalKey);
   }
 }

在注释1处,将回传过来的data赋值给dataToCache,看关键代码注释2

它的实现

//DecodeJob
public void reschedule() {
  runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
  callback.reschedule(this);
}

在这段代码中将runReason赋值为RunReason.SWITCH_TO_SOURCE_SERVICE,后面会用,接着下面还是会调用到DecodeJob的run方法,刚刚介绍过,会调用到runWrapped

private void runWrapped() {
  switch (runReason) {
    case INITIALIZE:
      stage = getNextStage(Stage.INITIALIZE);
      currentGenerator = getNextGenerator();
      runGenerators();
      break;
    case SWITCH_TO_SOURCE_SERVICE:
      runGenerators(); //1
      break;
    case DECODE_DATA:
      decodeFromRetrievedData();
      break;
    default:
      throw new IllegalStateException("Unrecognized run reason: " + runReason);
  }
}

根据刚刚赋值的runReason,这里会执行1,里面会调用到SourceGenerator的startNext,再来复习下

public boolean startNext() {
    if (dataToCache != null) {
      Object data = dataToCache;
      dataToCache = null;
      cacheData(data);  //1
    }
	//2
    if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
      return true;
    }
    sourceCacheGenerator = null;

  ...

注释1处

private void cacheData(Object dataToCache) {
 ...
   sourceCacheGenerator =
       new DataCacheGenerator(Collections.singletonList(loadData.sourceKey), helper, this);
 }

会创建sourceCacheGenerator

接着在注释2处调用它的startNext

public boolean startNext() {
..

  loadData = null;
  boolean started = false;
  while (!started && hasNextModelLoader()) {
    ModelLoader<File, ?> modelLoader = modelLoaders.get(modelLoaderIndex++);
    loadData =
        modelLoader.buildLoadData(cacheFile, helper.getWidth(), helper.getHeight(),
            helper.getOptions());
    if (loadData != null && helper.hasLoadPath(loadData.fetcher.getDataClass())) {
      started = true;
      loadData.fetcher.loadData(helper.getPriority(), this); //1
    }
  }
  return started;
}

这里的startNext和刚刚介绍的差不多,注释1处的loadData.fetcher是ByteBufferFileLoader,看下它的loadData

public void loadData(@NonNull Priority priority,
    @NonNull DataCallback<? super ByteBuffer> callback) {
  ByteBuffer result;
  try {
    result = ByteBufferUtil.fromFile(file); //1
  } catch (IOException e) {
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(TAG, "Failed to obtain ByteBuffer for file", e);
    }
    callback.onLoadFailed(e);
    return;
  }

  callback.onDataReady(result); //2
}

在注释1处将file转化为ByteBuffer,接着在注释2处将result返回出去

//DataCacheGenerator
@Override
public void onDataReady(Object data) {
  cb.onDataFetcherReady(sourceKey, data, loadData.fetcher, DataSource.DATA_DISK_CACHE, sourceKey);
}

//SourceGenerator  
@Override
public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
    DataSource dataSource, Key attemptedKey) {
  // This data fetcher will be loading from a File and provide the wrong data source, so override
  // with the data source of the original fetcher
  cb.onDataFetcherReady(sourceKey, data, fetcher, loadData.fetcher.getDataSource(), sourceKey);
}

//DecodeJob
@Override
public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
   DataSource dataSource, Key attemptedKey) {
 this.currentSourceKey = sourceKey;  
 this.currentData = data;
 this.currentFetcher = fetcher;
 this.currentDataSource = dataSource;
 this.currentAttemptingKey = attemptedKey;
 if (Thread.currentThread() != currentThread) {
   runReason = RunReason.DECODE_DATA;
   callback.reschedule(this);
 } else {
   GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
   try {
     decodeFromRetrievedData();  //1
   } finally {
     GlideTrace.endSection();
   }
 }
}

最后还是回调到DecodeJob的onDataFetcherReady,先是变量的赋值操作,接着看注释1处的代码

 private void decodeFromRetrievedData() {
...
   if (resource != null) {
     notifyEncodeAndRelease(resource, currentDataSource);  //1
   } else {
     runGenerators();
   }
 }

看关键代码注释1处

private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
  if (resource instanceof Initializable) {
    ((Initializable) resource).initialize();
  }

  Resource<R> result = resource;
  LockedResource<R> lockedResource = null;
  if (deferredEncodeManager.hasResourceToEncode()) {
    lockedResource = LockedResource.obtain(resource);
    result = lockedResource;
  }

  notifyComplete(result, dataSource);  //1

  stage = Stage.ENCODE;
  try {
    if (deferredEncodeManager.hasResourceToEncode()) {
      deferredEncodeManager.encode(diskCacheProvider, options);
    }
  } finally {
    if (lockedResource != null) {
      lockedResource.unlock();
    }
  }
  // Call onEncodeComplete outside the finally block so that it's not called if the encode process
  // throws.
  onEncodeComplete();
}

执行到关键代码注释1处,看下实现

private void notifyComplete(Resource<R> resource, DataSource dataSource) {
  setNotifiedOrThrow();
  callback.onResourceReady(resource, dataSource);
}
//EngineJob
public void onResourceReady(Resource<R> resource, DataSource dataSource) {
  synchronized (this) {
    this.resource = resource;
    this.dataSource = dataSource;
  }
  notifyCallbacksOfResult();
}

notifyComplete内部会通过callback回调到EngineJob的onResourceReady,然后调用notifyCallbacksOfResult

void notifyCallbacksOfResult() {
  ResourceCallbacksAndExecutors copy;
  Key localKey;
  EngineResource<?> localResource;
  synchronized (this) {
 ...
  for (final ResourceCallbackAndExecutor entry : copy) {
    entry.executor.execute(new CallResourceReady(entry.cb)); //1
  }
 ...
}

看关键代码注释1处,从代码可以看到是用到了线程池,它的实现是

Executors.mainThreadExecutor()

private static final Executor MAIN_THREAD_EXECUTOR =
    new Executor() {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override
      public void execute(@NonNull Runnable command) {
        handler.post(command);
      }
    };

它里面封装了一个Handler,这里就是用来将线程切换到了主线程

再来看CallResourceReady的run方法

@Override
public void run() {
  synchronized (EngineJob.this) {
    if (cbs.contains(cb)) {
      // Acquire for this particular callback.
      engineResource.acquire();
      callCallbackOnResourceReady(cb);  //1
      removeCallback(cb);
    }
    decrementPendingCallbacks();
  }
}

看关键代码注释1处,会执行cb

synchronized void callCallbackOnResourceReady(ResourceCallback cb) {
  try {
    // This is overly broad, some Glide code is actually called here, but it's much
    // simpler to encapsulate here than to do so at the actual call point in the
    // Request implementation.
    cb.onResourceReady(engineResource, dataSource);
  } catch (Throwable t) {
    throw new CallbackException(t);
  }
}

//SingleRequest
public synchronized void onResourceReady(Resource<?> resource, DataSource dataSource) {
...
  onResourceReady((Resource<R>) resource, (R) received, dataSource);
}

//SingleRequest
private synchronized void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
 ...
    if (!anyListenerHandledUpdatingTarget) {
      Transition<? super R> animation =
          animationFactory.build(dataSource, isFirstResource);
      target.onResourceReady(result, animation);  //
    }
  } finally {
    isCallingCallbacks = false;
  }

...
}

这段代码看到了target,会调用到onResourceReady

//ImageViewTarget
public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
  if (transition == null || !transition.transition(resource, this)) {
    setResourceInternal(resource);
  } else {
    maybeUpdateAnimatable(resource);
  }
}

//ImageViewTarget
private void setResourceInternal(@Nullable Z resource) {
  // Order matters here. Set the resource first to make sure that the Drawable has a valid and
  // non-null Callback before starting it.
  setResource(resource);
  maybeUpdateAnimatable(resource);
}

//DrawableImageViewTarget
@Override
protected void setResource(@Nullable Drawable resource) {
  view.setImageDrawable(resource);
}

到了这里最后还是通过调用ImageView的setImageDrawable来设置资源图片


5、总结

到了这里基本源码分析执行流程就完了,很多流程都省了,因为很多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值