注:这是基于4.10.0的源码
先上一张时序图:
Glide-时序图.png
先来看glide使用
Glide.with(this)
.load("http://goo.gl/gEgYUd")
.into(iv_test)
into 之前主要是做一些初始化操作,构建单例的Glide,创建空的fragment来感知生命周期,这里就不做介绍来看into之后做了什么
@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
//检查线程
Util.assertMainThread();
//判断null
Preconditions.checkNotNull(view);
//判断view自身是否设置了ScaleType
BaseRequestOptions<?> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
// Clone in this method so that if we use this RequestBuilder to load into a View and then
// into a different target, we don't retain the transformation applied based on the previous
// View's scale type.
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.
}
}
//调用into方法
//注意第一个参数,返回的是一个DrawableImageViewTarget对象
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
@NonNull
@Synthetic
<Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
Executor callbackExecutor) {
//继续调用自身
return into(target, targetListener, /*options=*/ this, callbackExecutor);
}
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
//构建一个请求
Request request = buildRequest(target, targetListener, options, callbackExecutor);
//从target中获取请求
Request previous = target.getRequest();
//请求是同一个
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
if (!Preconditions.checkNotNull(previous).isRunning()) {
//开启请求
previous.begin();
}
return target;
}
//不是同一个,清除
requestManager.clear(target);
//将请求设置到target
target.setRequest(request);
//添加到requestManager中,并开启请求,也就是request.begin方法
//就是这一个,将请求绑定生命周期
requestManager.track(target, request);
return target;
}
通过上面可以知道,主要就是构建一个request,然后调用begin方法,下面看如何构建请求
private Request buildRequest(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(
/*requestLock=*/ new Object(),
target,
targetListener,
/*parentCoordinator=*/ null,
transitionOptions,
requestOptions.getPriority(),
requestOptions.getOverrideWidth(),
requestOptions.getOverrideHeight(),
requestOptions,
callbackExecutor);
}
private Request buildRequestRecursive(
Object requestLock,
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
// Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
ErrorRequestCoordinator errorRequestCoordinator = null;
//默认为null
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
Request mainRequest =
buildThumbnailRequestRecursive(
requestLock,
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
//....
}
private Request buildThumbnailRequestRecursive(
Object requestLock,
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
//....
//假设没有做任何的操作,则直接返回这个
return obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
}
先假设没有配置缩略图什么的,所以直接返回的就是obtainRequest()方法返回的
private Request obtainRequest(
Object requestLock,
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
RequestCoordinator requestCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
Executor callbackExecutor) {
return SingleRequest.obtain(
context,
glideContext,
requestLock,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
glideContext.getEngine(),
transitionOptions.getTransitionFactory(),
callbackExecutor);
}
public static <R> SingleRequest<R> obtain(
Context context,
GlideContext glideContext,
Object requestLock,
Object model,
Class<R> transcodeClass,
BaseRequestOptions<?> requestOptions,
int overrideWidth,
int overrideHeight,
Priority priority,
Target<R> target,
RequestListener<R> targetListener,
@Nullable List<RequestListener<R>> requestListeners,
RequestCoordinator requestCoordinator,
Engine engine,
TransitionFactory<? super R> animationFactory,
Executor callbackExecutor) {
return new SingleRequest<>(
context,
glideContext,
requestLock,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
engine,
animationFactory,
callbackExecutor);
}
所以这个request就是一个SingleRequest对象,进入SingleRequest中的begin方法
@Override
public void begin() {
synchronized (requestLock) {
assertNotCallingCallbacks();
stateVerifier.throwIfRecycled();
startTime = LogTime.getLogTime();
//判断model是否赋值,注意这个model是我们调用load()中传进来的
//这里传进来的是一个string类型的地址
if (model == null) {
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
width = overrideWidth;
height = overrideHeight;
}
// Only log at more verbose log levels if the user has set a fallback drawable, because
// fallback Drawables indicate the user expects null models occasionally.
int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
//调用失败方法
onLoadFailed(new GlideException("Received null model"), logLevel);
return;
}
//如果已经在运行,抛出异常
if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}
//如果已经完成,调用onResourceReady
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
// 将状态至为获取尺寸
status = Status.WAITING_FOR_SIZE;
//如果尺寸可用,调用onSizeReady方法
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
//调用获取尺寸,最后会回调到onSizeReady方法
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));
}
}
}
不过尺寸是否可用,在的到尺寸之后都会回调到onSizeReady()方法
@Override
public void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
synchronized (requestLock) {
if (IS_VERBOSE_LOGGABLE) {
logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
//如果不是获取尺寸回调,返回
if (status != Status.WAITING_FOR_SIZE) {
return;
}
//将状态至为运行汇总
status = Status.RUNNING;
//获取宽高
float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
if (IS_VERBOSE_LOGGABLE) {
logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
}
//调用load,获取
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 <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;
//构建一个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);
}
}
//内存中获取成功,回调出去
cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
return null;
}
loadFromMemory()方法就是从内存中获取资源,默认在内存中没有,所以调用waitForExistingOrStartNewJob()方法获取
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
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是实现了Runnable
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);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Started new load", startTime, key);
}
return new LoadStatus(cb, engineJob);
}
上面中engineJob.start(decodeJob);就是通过一个线程池来执行Runnable,因为DecodeJob实现了Runnable,所以会走到DecodeJob的run方法中
@Override
public void run() {
//...
runWrapped();
//.....
}
private void runWrapped() {
//runReason默认为INITIALIZE
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);
}
}
上面这里就有点像策略模式,通过不同的策略来获取资源,也就是通过本地或网络获取图片,获取到对应的策略之后调用runGenerators()方法
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
//调用对应的startNext()方法
while (!isCancelled
&& currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
//如果startNext()返回false,则获取下一个Generator,
//也就是策略,然后在调用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.
}
根据getNextGenerator()方法返回的Generator来看,当第一次请求是,会走到SourceGenerator的startNext()方法中,也就是从网络中获取,我们看SourceGenerator的startNext()方法
@Override
public boolean startNext() {
//第一次dataToCache为null
if (dataToCache != null) {
Object data = dataToCache;
dataToCache = null;
cacheData(data);
}
//sourceCacheGenerator也为null
if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
return true;
}
sourceCacheGenerator = null;
loadData = null;
boolean started = false;
//通过while,来获取
while (!started && hasNextModelLoader()) {
//获取可用的获取资源列表
loadData = helper.getLoadData().get(loadDataListIndex++);
//判断是否可用
if (loadData != null
&& (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
|| helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
//可用将started至为true
started = true;
//获取资源
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}
其中这里是我觉得比较绕的地方,就是如何判断获取的是哪个,先来看helper.getLoadData()获取的列表是什么
List<LoadData<?>> getLoadData() {
if (!isLoadDataSet) {
isLoadDataSet = true;
loadData.clear();
//获取前面注册的,这里的model就是我们的string类型地址
List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
//noinspection ForLoopReplaceableByForEach to improve perf
for (int i = 0, size = modelLoaders.size(); i < size; i++) {
ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
//注意这里,调用了buildLoadData()方法
LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
if (current != null) {
loadData.add(current);
}
}
}
return loadData;
}
又通过glideContext.getRegistry().getModelLoaders(model);来获取
@NonNull
public <Model> List<ModelLoader<Model, ?>> getModelLoaders(@NonNull Model model) {
//通过getModelLoaders方法获取
List<ModelLoader<Model, ?>> result = modelLoaderRegistry.getModelLoaders(model);
if (result.isEmpty()) {
throw new NoModelLoaderAvailableException(model);
}
return result;
}
@NonNull
public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
//通过getModelLoadersForClass获取
List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(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中
filteredLoaders.add(loader);
}
}
return filteredLoaders;
}
这里又通过getModelLoadersForClass()方法来获取
@NonNull
private synchronized <A> List<ModelLoader<A, ?>> getModelLoadersForClass(
@NonNull Class<A> modelClass) {
//通过缓存获取
List<ModelLoader<A, ?>> loaders = cache.get(modelClass);
if (loaders == null) {
//缓存为null,通过multiModelLoaderFactory.build(modelClass)方法获取
//其中modelClass为String.class
loaders = Collections.unmodifiableList(multiModelLoaderFactory.build(modelClass));
cache.put(modelClass, loaders);
}
return loaders;
}
又通过multiModelLoaderFactory.build(modelClass)来获取,需要注意的是modelClass为String.class
@NonNull
synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
try {
List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
//循环entries
for (Entry<?, ?> entry : entries) {
//如果已经添加了,continue
if (alreadyUsedEntries.contains(entry)) {
continue;
}
//判断是否可用
if (entry.handles(modelClass)) {
alreadyUsedEntries.add(entry);
//如果可用,调用build方法,build方法就是:entry.factory.build(this)
loaders.add(this.<Model, Object>build(entry));
alreadyUsedEntries.remove(entry);
}
}
return loaders;
} catch (Throwable t) {
alreadyUsedEntries.clear();
throw t;
}
}
其中entries是在Glide构造方法中添加数据的
//构造方法中,就是通过append来给前面的entries数组添加值的
registry
.append(ByteBuffer.class, new ByteBufferEncoder())
//...
根据前面的,因为modelClass为String.class,所以只需要找下面这些
.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())
其中第三个参数就是factory,所以这里添加的就是这里对应的factory中build方法返回的然后现在往回走,回到helper.getLoadData()方法中
List<LoadData<?>> getLoadData() {
if (!isLoadDataSet) {
isLoadDataSet = true;
loadData.clear();
//我们已经知道了这个list里的值是什么了
List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
//noinspection ForLoopReplaceableByForEach to improve perf
for (int i = 0, size = modelLoaders.size(); i < size; i++) {
ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
//调用buildLoadData()方法
LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
if (current != null) {
loadData.add(current);
}
}
}
return loadData;
}
然后再调用buildLoadData()方法,就是前面我们看的factory.build()返回值的buildLoadData()方法,我以第一个来举例,也就是DataUrlLoader.StreamFactory<String>()
@NonNull
@Override
public ModelLoader<Model, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
//返回DataUrlLoader对象
return new DataUrlLoader<>(opener);
}
这个返回的是一个DataUrlLoader对象
public DataUrlLoader(DataDecoder<Data> dataDecoder) {
this.dataDecoder = dataDecoder;
}
@Override
public LoadData<Data> buildLoadData(
@NonNull Model model, int width, int height, @NonNull Options options) {
//正常会走来这里
return new LoadData<>(
new ObjectKey(model), new DataUriFetcher<>(model.toString(), dataDecoder));
}
@Override
public boolean handles(@NonNull Model model) {
//注意这里返回的false
return model.toString().startsWith(DATA_SCHEME_IMAGE);
}
正常会走buildLoadData()方法,但是这里handles()方法判断返回的是false,前面我们在添加的时候会判断handles()方法,如果返回false,则不添加,所以这个不符合,会走到下一个,也就是StringLoader.StreamFactory()中
@NonNull
@Override
public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
//返回StringLoader,注意这里里面又调用了multiFactory.build(Uri.class, InputStream.class)
//相当于又从新找了一遍
return new StringLoader<>(multiFactory.build(Uri.class, InputStream.class));
}
返回StringLoader,去看StringLoader
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);
//判断又判断了handles
if (uri == null || !uriLoader.handles(uri)) {
return null;
}
//返回的是buildLoadData()方法
return uriLoader.buildLoadData(uri, width, height, options);
}
@Override
public boolean handles(@NonNull String model) {
//这里返回true
return true;
}
所以,又调了一遍multiFactory.build(Uri.class, InputStream.class),注意这里的类型变成了Uri.class, InputStream.class,所以我们在去Glide构造方法中找对应的
.append(Uri.class, InputStream.class, new DataUrlLoader.StreamFactory<Uri>())
.append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
.append(Uri.class, InputStream.class, new AssetUriLoader.StreamFactory(context.getAssets()))
.append(Uri.class, InputStream.class, new MediaStoreImageThumbLoader.Factory(context))
.append(Uri.class, InputStream.class, new MediaStoreVideoThumbLoader.Factory(context))
.append(Uri.class, InputStream.class, new UriLoader.StreamFactory(contentResolver))
.append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())
然后又通过factory.build()的返回值的来判断handle()方法,到这里,然后回到最开始的地方
//还记得这个循环吗,前面获取的
while (!started && hasNextModelLoader()) {
//现在我们已经知道这个list里的内容是什么了
loadData = helper.getLoadData().get(loadDataListIndex++);
//通过这里来判断loadData.fetcher.getDataSourc
//其中loadData.fetcher就是我们factory.build()的返回值的buildLoadData()方法返回的内容
if (loadData != null
&& (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
|| helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
started = true;
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
根据helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource()这个判断,我们找到可用的就是下面这个
.append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
来看这个factory
public ModelLoader<Uri, InputStream> build(MultiModelLoaderFactory multiFactory) {
//又来一遍,不过类型变成了GlideUrl.class, InputStream.class
return new HttpUriLoader(multiFactory.build(GlideUrl.class, InputStream.class));
}
public HttpUriLoader(ModelLoader<GlideUrl, InputStream> urlLoader) {
this.urlLoader = urlLoader;
}
@Override
public LoadData<InputStream> buildLoadData(
@NonNull Uri model, int width, int height, @NonNull Options options) {
return urlLoader.buildLoadData(new GlideUrl(model.toString()), width, height, options);
}
@Override
public boolean handles(@NonNull Uri model) {
return SCHEMES.contains(model.getScheme());
}
又来一遍,但是类型变成了GlideUrl.class, InputStream.class,这个类型只有一个
.append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
继续看这个factory
@NonNull
@Override
public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) {
return new HttpGlideUrlLoader(modelCache);
}
public HttpGlideUrlLoader(@Nullable ModelCache<GlideUrl, GlideUrl> modelCache) {
this.modelCache = modelCache;
}
@Override
public LoadData<InputStream> buildLoadData(
@NonNull GlideUrl model, int width, int height, @NonNull Options options) {
// GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time
// spent parsing urls.
GlideUrl url = model;
if (modelCache != null) {
url = modelCache.get(model, 0, 0);
if (url == null) {
modelCache.put(model, 0, 0, model);
url = model;
}
}
int timeout = options.get(TIMEOUT);
//最后会返回的是这里
return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
}
@Override
public boolean handles(@NonNull GlideUrl model) {
return true;
}
所以loadData.fetcher.loadData(helper.getPriority(), this);中的fetcher就是上面的HttpUrlFetcher。
网友评论