load时序图:
RequestBuilder : 这是一个通用请求构建类,可以处理通用资源类型的设置选项
和启动负载。
load 函数加载相对于比较简单。我们看下具体代码实现
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
.....
public RequestBuilder<Drawable> load(@Nullable String string) {
//这里调用 Drawable 图片加载请求器为其加载
return asDrawable().load(string);
}
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable Uri uri) {
return asDrawable().load(uri);
}
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable File file) {
return asDrawable().load(file);
}
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass,
context);
}
}
看看load详情:
public class RequestBuilder<TranscodeType> extends
BaseRequestOptions<RequestBuilder<TranscodeType>>
implements Cloneable,
ModelTypes<RequestBuilder<TranscodeType>> {
public RequestBuilder<TranscodeType> load(@Nullable String
string) {
return loadGeneric(string);
}
// 描述加载的数据源-这里可以看做是我们刚刚传递进来的 http://xxxx.png
@Nullable private Object model;
// 描述这个请求是否已经添加了加载的数据源
private boolean isModelSet;
private RequestBuilder<TranscodeType> loadGeneric(@Nullable
Object model) {
this.model = model;
isModelSet = true;
return this;
}
}
到这里 RequestBuilder 就构建好了, RequestBuilder构建出来后,都是
为了后面的into
into时序图:
@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull
ImageView view) {
Util.assertMainThread();
Preconditions.checkNotNull(view);
// 根据 ImageView 布局中的 scaleType 来重构 requestOptions
BaseRequestOptions<?> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
//如果在 xml ImageView 节点中 没有设置 scaleType 那么默认在构造函数
中进行了初始化为 mScaleType = ScaleType.FIT_CENTER;
switch (view.getScaleType()) {
.....
case FIT_CENTER:
case FIT_START:
case FIT_END:
//这里用到了克隆(原型设计模式),选择一个 居中合适 显示的方案,同学
们会发现,到处都是设计模式,它不是为了装B哦
requestOptions =
requestOptions.clone().optionalFitCenter();
break;
....
}
}
//调用 into 重载函数,创建一个 ViewTarget
return into(
//调用 buildImageViewTarget 构建一个 ImageView 类型的
Target(Bitmap/Drawable)
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
上面代码就两大步:
第一步:先拿到当前 ImageView getScaleType 类型的属性,然后重新 clone 一个进
行配置;
第二步:调用 into 重载继续构建;
同学们先来看下 glideContext.buildImageViewTarget 是怎么构建出来
ImageViewTarget 的:
@NonNull
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X>
transcodeClass) {
//调用 工厂模式 根据 transcodeClass 生成出一个对应的
ImageViewTarget
return imageViewTargetFactory.buildTarget(imageView,
transcodeClass);
}
public class ImageViewTargetFactory {
@NonNull
@SuppressWarnings("unchecked")
public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull
ImageView view,
@NonNull Class<Z> clazz) {
//如果目标的编码类型属于 Bitmap 那么就创建一个 Bitmap 类型的
ImageViewTarget
if (Bitmap.class.equals(clazz)) {
return (ViewTarget<ImageView, Z>) new
BitmapImageViewTarget(view);
如果目标的编码类型属于 Drawable 那么就创建一个 Drawable 类型的
ImageViewTarget
} 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)");
}
}
}
上面 生产 Target 的时候注意一下,只要调用了 asBitmap 才会执行生
产 BitmapImageViewTarget ,所以这里我们关注 Drawable 类型就行了,我们就先
简单看看这个 target 内部怎么实现的
public class DrawableImageViewTarget extends
ImageViewTarget<Drawable> {
public DrawableImageViewTarget(ImageView view) {
super(view);
}
@SuppressWarnings({"unused", "deprecation"})
@Deprecated
public DrawableImageViewTarget(ImageView view, boolean
waitForLayout) {
super(view, waitForLayout);
}
@Override
protected void setResource(@Nullable Drawable resource) {
view.setImageDrawable(resource);
}
}
从上面代码可以知道 DrawableImageViewTarget 继承的是
ImageViewTarget 重写的 setResource 函数,实现了显示 Drawable 图片的逻辑,
好了,这里先有个印象就行,我们只管主线流程,支线细节先跳读,最后会讲到怎么
调用的。继续 into 重载
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;
}
以上核心就两个点:
第一点:为 target buildRequest 构建一个 Glide request 请求;
第二点:将构建出来的 Request 交于 RequestManager 来执行
private Request buildRequest(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(
target,
targetListener,
/*parentCoordinator=*/ null,
transitionOptions,
requestOptions.getPriority(),
requestOptions.getOverrideWidth(),
requestOptions.getOverrideHeight(),
requestOptions,
callbackExecutor);
}
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) {
return SingleRequest.obtain(
context,
glideContext,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
glideContext.getEngine(),
transitionOptions.getTransitionFactory(),
callbackExecutor);
}
最后我们发现是 SingleRequest.obtain 来为我们构建的 Request 请求对
象,开始只是初始化一些配置属性,下面我们就来找 begin 开始的地方, 先来看下
track 函数执行:
//这里对当前 class 加了一个同步锁避免线程引起的安全性
synchronized void track(@NonNull Target<?> target, @NonNull
Request request) {
//添加一个目标任务
targetTracker.track(target);
//执行 Glide request
requestTracker.runRequest(request);
}
//这里对当前 class 加了一个同步锁避免线程引起的安全性
synchronized void track(@NonNull Target<?> target, @NonNull
Request request) {
//添加一个目标任务
targetTracker.track(target);
//执行 Glide request
requestTracker.runRequest(request);
}
public void runRequest(@NonNull Request request) {
//添加一个请求
requests.add(request);
//是否暂停
if (!isPaused) {
//没有暂停,开始调用 Request begin 执行
request.begin();
} else {
//如果调用了 暂停,清理请求
request.clear();
pendingRequests.add(request);
}
}
上面的逻辑是先为 requests 添加一个请求,看看是否是停止状态,如果不是就调
用 request.begin(); 执行。
这里的 Request 是一个接口,通过之前我们讲到 buildRequest 函数可知
Request 的实现类是 SingleRequest 我们就直接看它的 begin 函数.
@Override
public synchronized void begin() {
assertNotCallingCallbacks();
stateVerifier.throwIfRecycled();
startTime = LogTime.getLogTime();
if (model == null) {
//检查外部调用的尺寸是否有效
if (Util.isValidDimensions(overrideWidth, overrideHeight))
{
width = overrideWidth;
height = overrideHeight;
}
//失败的回调
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");
}
if (status == Status.COMPLETE) {
//表示资源准备好了
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
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());
}
if (IS_VERBOSE_LOGGABLE) {
logV("finished run method in " +
LogTime.getElapsedMillis(startTime));
}
}
我们直接看 onSizeReady:
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);
}
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) {
//拿到缓存或者请求的 key
EngineKey key = keyFactory.buildKey(model, signature, width,
height, transformations,
resourceClass, transcodeClass, options);
//根据 key 拿到活动缓存中的资源
EngineResource<?> active = loadFromActiveResources(key,
isMemoryCacheable);
//如果 ActiveResources 活动缓存中有就回调出去
if (active != null) {
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
return null;
}
//尝试从 LruResourceCache 中找寻这个资源
EngineResource<?> cached = loadFromCache(key,
isMemoryCacheable);
if (cached != null) {
//如果内存缓存 Lru 中资源存在回调出去
cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
return null;
}
//------------- 走到这里说明活动缓存 跟内存 缓存都没有找到 ----------
-
//根据 Key 看看缓存中是否正在执行
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<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);
//把当前需要执行的 key 添加进缓存
jobs.put(key, engineJob);
//执行任务的回调
engineJob.addCallback(cb, callbackExecutor);
//开始执行。
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}
通过 engine.load 这个函数里面的逻辑,同学们我们可以总结3点:
1. 先构建请求或者缓存 KEY ;
2. 根据 KEY 从内存缓存中查找对应的资源数据(ActiveResources(活动缓存,内部
是一个 Map 用弱引用持有),LruResourceCache),如果有就回调 对应监听的
onResourceReady 表示数据准备好了。
3. 从执行缓存中查找对应 key 的任务
1. 如果找到了,就说明已经正在执行了,不用重复执行。
2. 没有找到,通过 EngineJob.start 开启一个新的请求任务执行。
同学们下面我们就来看下 engineJob.start 具体执行逻辑:
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
//拿到 Glide 执行的线程池
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
//开始执行
executor.execute(decodeJob);
}
通过 DecodeJob 源码得知,它是实现的 Runnable 接口,这里 GlideExecutor 线程
池开始执行,就会启动 DecodeJob 的 run 函数,我们跟踪 run 的实现:
class DecodeJob<R> implements
DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable<DecodeJob<?>>,
Poolable {
// 线程执行调用 run
@Override
public void run() {
GlideTrace.beginSectionFormat("DecodeJob#run(model=%s)",
model);
DataFetcher<?> localFetcher = currentFetcher;
try {
//是否取消了当前请求
if (isCancelled) {
notifyFailed();
return;
}
//执行
runWrapped();
} catch (CallbackException e) {
.....//一些错误回调
}
}
分析runWrapped:
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 源数据执行
器。继续下面代码执行:
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
//判断是否取消,是否开始
//调用 DataFetcherGenerator.startNext() 判断是否是属于开始执行的任
务
while (!isCancelled && currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
....
}
上面代码先看 currentGenerator.startNext() 这句代码,
DataFetcherGenerator 是一个抽象类,那么这里执行的实现类是哪一个,可以参
考下面说明:
Stage.RESOURCE_CACHE【状态标记】 ---- 从磁盘中获取缓存的资源数据【作用】 -
-- ResourceCacheGenerator【执行器】
Stage.DATA_CACHE【状态标记】 ---- 从磁盘中获取缓存的源数据【作用】 ---
DataCacheGenerator【执行器】
Stage.SOURCE【状态标记】 --- 一次新的请求任务 --- SourceGenerator【执行器】
因为这里我们没有配置缓存,那么直接看 SourceGenerator
@Override
public boolean startNext() {
...
loadData = null;
boolean started = false;
while (!started && hasNextModelLoader()) {
//获取一个 ModelLoad 加载器
loadData = helper.getLoadData().get(loadDataListIndex++);
if (loadData != null
&&
(helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.g
etDataSource())
||
helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
started = true;
//使用加载器中的 fetcher 根据优先级加载数据
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}
helper.getLoadData() 获取的是一个什么样的加载器,我们可以先
猜一下,因为没有配置任何缓存,所以可以猜得到是 http 请求了,那么是不是猜测
的那样的
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;
}
首先拿到一个加载器的容器,加载器是在 Glide 初始化的时候 通过
Registry.append() 添加的,所以,
ModelLoad 的实现类是 HttpGlideUrlLoader 加载器,我们看下它的具体实现:
@Override
public LoadData<InputStream> buildLoadData(@NonNull GlideUrl
model, int width, int height,
@NonNull Options options) {
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));
}
这里看到是返回的一个 HttpUrlFetcher 给加载器。加载器我们拿到了,现在开始
加载,返回到刚刚的源码,请看下面:
class DataCacheGenerator implements DataFetcherGenerator,
DataFetcher.DataCallback<Object> {
//挑重要代码
@Override
public boolean startNext() {
....
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);
}
}
return started;
}
}
这里拿到的加载器是 HttpUrlFetcher 所以我们直接看它的
loadData 实现:
@Override
public void loadData(@NonNull Priority priority,
@NonNull DataCallback<? super InputStream> callback) {
long startTime = LogTime.getLogTime();
try {
//http 请求,返回一个 InputStream 输入流
InputStream result =
loadDataWithRedirects(glideUrl.toURL(), 0, null,
glideUrl.getHeaders());
//将 InputStream 以回调形式回调出去
callback.onDataReady(result);
} catch (IOException e) {
callback.onLoadFailed(e);
} finally {
...
}
}
loadDataWithRedirects 这个函数是怎么生成的一个InputStream :
private InputStream loadDataWithRedirects(URL url, int
redirects, URL lastUrl,
Map<String, String> headers) throws IOException {
if (redirects >= MAXIMUM_REDIRECTS) {
throw new HttpException("Too many (> " + MAXIMUM_REDIRECTS
+ ") redirects!");
} else {
try {
if (lastUrl != null &&
url.toURI().equals(lastUrl.toURI())) {
throw new HttpException("In re-direct loop");
}
} catch (URISyntaxException e) {
// Do nothing, this is best effort.
}
}
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);
urlConnection.setInstanceFollowRedirects(false);
urlConnection.connect();
stream = urlConnection.getInputStream();
if (isCancelled) {
return null;
}
final int statusCode = urlConnection.getResponseCode();
if (isHttpOk(statusCode)) {
return getStreamForSuccessfulRequest(urlConnection);
}
...//抛的异常我们暂时先不管
}
这里是 HttpURLConnection 作为 Glide 底层
成网络请求的。请求成功之后直接返回的是一个输入流,最后会通过 onDataReady
回调到 DecodeJob onDataFetcherReady 函数中。回调到
SourceGenerator :
@Override
public void onDataReady(Object data) {
DiskCacheStrategy diskCacheStrategy =
helper.getDiskCacheStrategy();
if (data != null &&
diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource(
))) {
dataToCache = data;
cb.reschedule();
} else {
cb.onDataFetcherReady(loadData.sourceKey, data,
loadData.fetcher,
loadData.fetcher.getDataSource(), originalKey);
}
}
这里会有 else 因为我们没有配置缓存,继续回调:
class DecodeJob<R> implements
DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable<DecodeJob<?>>,
Poolable {
...
@Override
public void onDataFetcherReady(Key sourceKey, Object data,
DataFetcher<?> fetcher,
DataSource dataSource, Key attemptedKey) {
this.currentSourceKey = sourceKey; //当前返回数据的 key
this.currentData = data; //返回的数据
this.currentFetcher = fetcher; //返回的数据执行器,这里可以理解
为 HttpUrlFetcher
this.currentDataSource = dataSource; //数据来源 url
this.currentAttemptingKey = attemptedKey;
if (Thread.currentThread() != currentThread) {
runReason = RunReason.DECODE_DATA;
callback.reschedule(this);
} else {
GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
try {
//解析返回回来的数据
decodeFromRetrievedData();
} finally {
GlideTrace.endSection();
}
}
}
...
}
//解析返回的数据
private void decodeFromRetrievedData() {
Resource<R> resource = null;
try {
// 调用 decodeFrom 解析 数据;HttpUrlFetcher , InputStream ,
currentDataSource
resource = decodeFromData(currentFetcher, currentData,
currentDataSource);
} catch (GlideException e) {
e.setLoggingDetails(currentAttemptingKey,
currentDataSource);
throwables.add(e);
}
//解析完成后,通知下去
if (resource != null) {
notifyEncodeAndRelease(resource, currentDataSource);
} else {
runGenerators();
}
}
继续跟 decodeFromData 看看怎么解析成 Resource 的:
private <Data> Resource<R> decodeFromData(DataFetcher<?>
fetcher, Data data,
DataSource dataSource) throws GlideException {
...
Resource<R> result = decodeFromFetcher(data, dataSource);
....
return result;
} finally {
fetcher.cleanup();
}
}
@SuppressWarnings("unchecked")
private <Data> Resource<R> decodeFromFetcher(Data data,
DataSource dataSource)
throws GlideException {
//获取当前数据类的解析器 LoadPath
LoadPath<Data, ?, R> path =
decodeHelper.getLoadPath((Class<Data>) data.getClass());
//通过 LoadPath 解析器来解析数据
return runLoadPath(data, dataSource, path);
}
private <Data, ResourceType> Resource<R> runLoadPath(Data data,
DataSource dataSource,
LoadPath<Data, ResourceType, R> path) throws GlideException
{
Options options = getOptionsWithHardwareConfig(dataSource);
//因为这里返回的是一个 InputStream 所以 这里拿到的是
InputStreamRewinder
DataRewinder<Data> rewinder =
glideContext.getRegistry().getRewinder(data);
try {
//将解析资源的任务转移到 Load.path 方法中
return path.load(
rewinder, options, width, height, new
DecodeCallback<ResourceType>(dataSource));
} finally {
rewinder.cleanup();
}
}
为了解析数据首先构建一个 LoadPath, 然后创建一个
InputStreamRewinder 类型的 DataRewinder, 最终将数据解析的操作放到了
LoadPath.load 方法中
最后
以上就是含糊大门最近收集整理的关于Glide解析(二)的全部内容,更多相关Glide解析(二)内容请搜索靠谱客的其他文章。
发表评论 取消回复