熟悉Glide使用
分析Glide.with(context).load(url).into(view) 的内部实现
初始化流程和获取RequestManager
Glide.with(context)会获取一个RequestManager对象. 在这个过程中涉及到
- Glide 初始化
- RequestManagerRetriever
接下来一步步分析.
Glide.with(this).load(IMG_URL).into(mBinding.ivImg);
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getContext()).get(fragment);
}@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever();
}
@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;
}
- 通过代码可知, Glide通过单例模式(饿汉式)实现全局只有一个对象, 饿汉式创建对象时,会使用双重检测的方式实现, 根据 volatile 关键可知, 每次使用时从主内存获取最新值,可以防止出现,创建多个对象的情况.
- GenerateAppGlideModule 通过反射创建对象, GenerateAppGlideModule是一个抽象类,具体实现是编译阶段生成的一个GenerateAppGlideModuleImpl对象,但是这个对象没有在源码中. Java反射的本质是获取class对象, 通过class对象来操作它的方法和属性.
@GuardedBy("Glide.class")
private static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
// In the thread running initGlide(), one or more classes may call Glide.get(context).
// Without this check, those calls could trigger infinite recursion.
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;
}
method: initializeGlide(Context context, GlideBuilder builder, GeneratedAppGlideModule annotationGeneratedModule) {
...
Glide glide = builder.build(applicationContext);
...
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
上面代码主要做两件事, 通过构建者模式创建Glide对象, 在ApplicationContext 监听 trimMemory 回调.
@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();
}
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(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
if (defaultRequestListeners == null) {
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
isLoggingRequestOriginsEnabled,
isImageDecoderEnabledForBitmaps);
}
这个是创建Glide的主要代码.
- 创建GlideExecutor, 线程池对象,会放在Engine对象里面, 这个对象在后面用于创建 EngineJob, DecodeJob, 并执行DecodeJob, DecodeJob执行网络请求, Bitmap处理, 缓存处理和页面展示功能
- BitmapPool 对象使用了, Options.inBitmap 属性, 封装了Android复用Bitmap的逻辑
- memoryCache Glide 内存缓存机制
- connectivityMonitorFactory 网络监听, 断网时会取消所有请求
- requestManagerRetriever 设置RequestManager 缓存管理对象
- 创建Glide对象.
上面流程走完之后就创建了Glide对象, 内存相关内容之后再说. 其中的一些对象也可以在展开Glide的细节研究时再细说.
回到主线, 这个时候就要获取到RequestManagerRetriever对象, 然后从中获取RequestManager对象. 创建Glide对象时, 会传递一个RequestManagerRetriever对象参数,这个对象就是要获取的RequestManagerRetriever对象.
@NonNull
public RequestManager get(@NonNull Fragment fragment) {
Preconditions.checkNotNull(
fragment.getContext(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getContext().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
}
}
@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;
}
@Override
这个方法会先获取一个SupportRequestManagerFragment对象,这个Fragment里面保存有一个RequestManager对象, 如果为空就创建,然后保存到SupportRequestManagerFragment中,再把这个Fragment保存在FragmentManager中,或者是Retriever对象的pendingSupportRequestManagerFragments MAP里面.
RequestManager 对象会和 lifecycle 对象关联, lifecycle 和 Fragment 是关联的, 监听Fragment生命周期的变化, 如果Fragment走到 onStop 或 onDestory 则RequestManager会相应的暂停请求或终止请求并清空相应资源. 如何实现的后面会再研究.
遗留问题, RequestManager的管理问题, 请求取消的实现
RequestBuilder对象
获取RequestManager对象之后调用load(URL)方法之后就会创建RequestBuilder对象
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
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();
initRequestListeners(requestManager.getDefaultRequestListeners());
apply(requestManager.getDefaultRequestOptions());
}
- 在上面代码中需要注意的是 asDrawable() 方法, 这个方法会把 RequestBuilder对象的resourceClass设置为Drawable.class, 这个和后面的图片处理有关
- RequestBuilder 看名字知道是一个构建者模式的Builder, 所有参数的设置都是通过apply()方法实现
public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
上面方法设置了model, 这个和获取图片的方式有关.至此RequestBuilder的设置就完成了.
into(view)
这个方法涉及到Glide的主要逻辑所以会更复杂.
method: into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor()) {
Request request = buildRequest(target, targetListener, options, callbackExecutor); requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
}
- into 方法会创建一个DrawableImageViewTarget对象, 主要是根据 transcodeClass对象实现, 其实就是asDrawable()这个方法实现.Executors.mainThreadExecutor() 通过Looper.MainLoop实现.
- buildRequest()方法最终会创建一个SingleRequest对象
- 把Request方法RequestManager对象的set集合内,进行管理和取消操作.
其实到这里大体上脉络就出来了, 每个Fragment或Activity就是一个RequestManager对象, 管理当前组件生命周期内的图片请求. 每一个请求对应一个Request对象, 这个对象通过构建者模式创建.
Request 内部逻辑
request 被添加到RequestManager后通过调begin()方法开始
method: begin() {
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());
}
}
begin()方法会等待尺寸确定好之后在执行其他请求操作, 如果View还没有确定尺寸会通过设置View.getViewTreeObserver设置监听, 之后会调用onSizeReady()
method: onSizeReady(width, height) {
status = Status.RUNNING;
float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
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);
// This is a hack that's only useful for testing right now where loads complete synchronously
// even though under any executor running on any thread but the main thread, the load would
// have completed asynchronously.
if (status != Status.RUNNING) {
loadStatus = null;
}
}
最后设置status 为初始化状态且通过engine对象开始加载过程. engine对象是Glide对象创建时设置的.
method: load(args...) {
// 缓存key
EngineKey key =
keyFactory.buildKey(
model,
signature,
width,
height,
transformations,
resourceClass,
transcodeClass,
options);
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);
}
}
这个方法会先从缓存中获取key对应的 resource, 如果没获取到就执行 waitForExistingOrStartNewJob()方法, Glide的内存缓存有两部分,分别是ActiveRes 和 MemoryRes.内存缓存相关内容之后再继续分析.
Engine.method: waitForExistingOrStartNewJob() {
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
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);
}
- waitForExistingOrStartNewJob() 方法是Engine的一个方法, 所有的图片请求对应的就是Engine里的一个Job对象, 这个对象被缓存到了Engine.job属性内.
- 所有的请求, 编解码操作都在DecodeJob内实现, EngineJob 是Callback回调的中间处理者
DecodeJob 内部逻辑
我现在虽然知道Glide的内部实现逻辑, 但是一些结构性的东西还是没有理解.
Registry
注册表管理类.
注释信息描述这个类用于管理组合Glide的加载,解码和编码的逻辑,并支持替换和扩展. 因为涉及到的代码太多所以从 model = String.class为出发点进行分析
- Registry 内部有多个 XXXRegistry类, 用于不同的目的,其中
- ModelLoaderRegistry 和加载相关
- EncoderRegistry和ResourceEncoderRegistry 和编码相关
- ResourceDecoderRegistry 和解码相关
// 在Glide的构造函数中
Glide.method: construct() {
registry
.append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())
.append(String.class, InputStream.class, new StringLoader.StreamFactory())
.append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
.append(
String.class, AssetFileDescriptor.class, new StringLoader.AssetFileDescriptorFactory())
}
@NonNull
public <Model, Data> Registry append(
@NonNull Class<Model> modelClass,
@NonNull Class<Data> dataClass,
@NonNull ModelLoaderFactory<Model, Data> factory) {
modelLoaderRegistry.append(modelClass, dataClass, factory);
return this;
}
上面方法中registry.append()注册表的内容都保存在modelLoaderRegistry中, 这个是和加载相关的逻辑.
ModelLoaderRegistry.method::append(
@NonNull Class<Model> modelClass,
@NonNull Class<Data> dataClass,
@NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
multiModelLoaderFactory.append(modelClass, dataClass, factory);
cache.clear();
}
MultiModelLoaderFactory:: synchronized <Model, Data> void append(
@NonNull Class<Model> modelClass,
@NonNull Class<Data> dataClass,
@NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
add(modelClass, dataClass, factory, /*append=*/ true);
}
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);
}
Entry对象主要是封装了 modelClass , dataClass 和 factory 这三者的关系, 其中 modelClass是数据加载的原始类型, 比如 String, dataClass是根据ModelClass获取到的数据类型,比如InputStream, factory 实现了这种转换关系.举个例子, 看下StringLoader.StreamFactory的实现和使用.
@NonNull
public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
if (modelLoaders.isEmpty()) {
throw new NoModelLoaderAvailableException(model);
}
int size = modelLoaders.size();
boolean isEmpty = true;
List<ModelLoader<A, ?>> filteredLoaders = Collections.emptyList();
//noinspection ForLoopReplaceableByForEach to improve perf
for (int i = 0; i < size; i++) {
ModelLoader<A, ?> loader = modelLoaders.get(i);
if (loader.handles(model)) {
if (isEmpty) {
filteredLoaders = new ArrayList<>(size - i);
isEmpty = false;
}
filteredLoaders.add(loader);
}
}
if (filteredLoaders.isEmpty()) {
throw new NoModelLoaderAvailableException(model, modelLoaders);
}
return filteredLoaders;
}
@NonNull
private synchronized <A> List<ModelLoader<A, ?>> getModelLoadersForClass(
@NonNull Class<A> modelClass) {
List<ModelLoader<A, ?>> loaders = cache.get(modelClass);
if (loaders == null) {
loaders = Collections.unmodifiableList(multiModelLoaderFactory.build(modelClass));
cache.put(modelClass, loaders);
}
return loaders;
}
@NonNull
synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
try {
List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
for (Entry<?, ?> entry : entries) {
// Avoid stack overflow recursively creating model loaders by only creating loaders in
// recursive requests if they haven't been created earlier in the chain. For example:
// A Uri loader may translate to another model, which in turn may translate back to a Uri.
// The original Uri loader won't be provided to the intermediate model loader, although
// other Uri loaders will be.
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;
}
}
上面代码比较多,具体分析如下.
- 根据model 获取对应的ModelLoad对象, 这个在Glide构造方法中已经注册过, 加载逻辑相关的都被放到了 ModelLoaderRegistry 中, 这个类由通过 MultiModelLoaderFactory 保存和处理这些注册信息.
- 会根据Model对象生成对应的ModelLoader对象, 并保存在ModelLoaderRegistry的cache全局变量中
- 遍历entires获取 Entry.handler(model) 为 true 的entry对象, 调用 entry.build(), 把生成的ModelLoader对象保存在list中.
@NonNull
@SuppressWarnings("unchecked")
private <Model, Data> ModelLoader<Model, Data> build(@NonNull Entry<?, ?> entry) {
return (ModelLoader<Model, Data>) Preconditions.checkNotNull(entry.factory.build(this));
}
调用Entry第三个对象的build()方法, 并把当前MultiModelLoaderFactory当做参数.
/** Factory for loading {@link InputStream}s from Strings. */
public static class StreamFactory implements ModelLoaderFactory<String, InputStream> {
@NonNull
@Override
public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
return new StringLoader<>(multiFactory.build(Uri.class, InputStream.class));
}
@Override
public void teardown() {
// Do nothing.
}
}
public StringLoader(ModelLoader<Uri, Data> uriLoader) {
this.uriLoader = uriLoader;
}
@Override
public LoadData<Data> buildLoadData(
@NonNull String model, int width, int height, @NonNull Options options) {
Uri uri = parseUri(model);
if (uri == null || !uriLoader.handles(uri)) {
return null;
}
return uriLoader.buildLoadData(uri, width, height, options);
}
通过上面代码可知, 调用build()会生成一个ModelLoader对象, 在上面代码中model是string.class, 所以生成的ModelLoader是 StringLoader 对象, 创建这个对象的时候需要给它的 urlLoader 赋值, 这个也是一个ModelLoader对象, 是一个 MultiModelLoader, 这样就通过代理的方式实现了, String -> InputStream
到 uri -> InputStream
的转换.
在Glide的构造方法中, URI的注册表比String多, 但是整体流程上是一样的. 所以就不多说了.
DataFetcherGenerator
Glide 的 DecodeJob 的实现原理是对 DataFetcherGenerator 的链式管理, 去对数据进行加载, 编解码操作, 所以接下来一步步分析他的实现, 现在再看代码不是去了解他内部的实现原理, 而是去明白它的设计理念.
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
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);
}
}
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() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
while (!isCancelled
&& currentGenerator != null
&& !(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();
}
// Otherwise a generator started a new load and we expect to be called back in
// onDataFetcherReady.
}
先说一下其中的一些属性的作用:
- stage 表明了当前的状态, 链表的排列顺序也是根据这个 stage 变化的.
- DecodeHelper 是逻辑执行的辅助类.
下面将根据Stage的值变化, 解析DecodeJob 执行逻辑.
/** Where we're trying to decode data from. */
private enum Stage {
/** The initial stage. */
INITIALIZE,
/** Decode from a cached resource. */
RESOURCE_CACHE,
/** Decode from cached source data. */
DATA_CACHE,
/** Decode from retrieved source. */
SOURCE,
/** Encoding transformed resources after a successful load. */
ENCODE,
/** No more viable stages. */
FINISHED,
}
Step One : Stage == INITIALIZE
- 通过上面的代码知道, INITIALIZE 下一步会给stage 和 currentGenerator 赋值, 这个值是根据 diskCacheStrategy.decodeCachedResource() 来确定的, 这个 diskCacheStrategy 是DiskCacheStrategy.AUTIOMIC, decodeCachedResource() 方法会返回 true.
- 之后 stage = Stage.RESOURCE_CACHE, currentGenerator = ResourceCacheGenerator.
- stage 的状态变化符合枚举的的顺序,先从缓存中获取,在从DataCahce中取,最后在请求数据
- 请求完后通过Callback变化,通知已完成.
Step Two: ResourceCacheGenerator.startNext()
ResourceCacheGenerator.method::startNext() {
List<Key> sourceIds = helper.getCacheKeys();
if (sourceIds.isEmpty()) {
return false;
}
List<Class<?>> resourceClasses = helper.getRegisteredResourceClasses();
if (resourceClasses.isEmpty()) {
if (File.class.equals(helper.getTranscodeClass())) {
return false;
}
throw new IllegalStateException(
"Failed to find any load path from "
+ helper.getModelClass()
+ " to "
+ helper.getTranscodeClass());
}
}
- getCacheKeys() 函数通过Glide.Registry 获取对应model的LoadData集合
- helper.getRegisteredResourceClasses() 可以获取到解析路径
- while 循环几次后退出循环返回 false
Step Three: Stage = DATA_CACHE
如果之前没有请求过数据,那个对应的DiskCache里面也就没对应的图片,所以要走下一步
Step Four: Stage = SOURCE
这个时候 currentGenerator 为 SourceGenerator, 它的作用就是根据model获取到对应的资源,不管是本地Res资源,还是远程服务资源. 获取资源的方式是ModelLoad, 会根据Model 获取到对应的数据, 获取数据的功能由fetch接口实现.
Step Five: LoadPath
LoadPath: 加载路径,在SourceGenerator加载之前就会先判断有没有对应的加载路径,加载路径对应 dataClass, ResourceType 和 Transcode, 但是具体的细节还没了解,最终会把dataclasss转换成Transcode, 这样就能获取到需要的资源, 这次需要的资源类型就是 Drawable.
Step Six: Decode
LoadPath里面有DecodePath, 里面有DecodeResource接口的实现类,Decode 就是用于解码数据,转换成Drawable. 然后再通过callback通知Engine, 最后调用Target的 onSourceReady()方法,给View设置对应的drawable.
这样Glide.with(context).load(url).into(view)
的整个流程就结束了。