1、时序图&流程图
2、第三步into的简略分析
- 上回说到Glide.whith(context).load("xxxxxx");返回了RequestBuilder
- 那么这回就是Glide.whit(context).load("xxxxxx").into(view);也就是into的事情了
2.1、拿到getScaleType类型的属性,Imageview的Imageview的 。clone一个进行配置
@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());
}
2.2、调用into重载继续构造
- 先看下glideContext.buildeImageViewTarget怎么构建出来的
- 只有调用了 asBitmap 才会执行生 BitmapImageViewTarget ,所以这里我们关注 Drawable 类型就行了
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)");
}
}
}
2.3、DrawableImageViewTarget
- 最终在view.setImageDrawable(resource);中设置了view的source
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 函数
2.4、以上内容核心
2.4.1、位target buildeRequets构建一个GlideRequets请求
2.4.2、将构建出来的Requetst交于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;
}
3、into详细讲解
3.1、在RequestBuilder中,构建Request,
3.1.1、RequestBuilder中调用SingleRequest.obtain来构建Request对象,开始就是配置一些属性。
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);
}
3.1.2、 requestManager.track(target, request);
- 先为 requests 添加一个请求,看看是否是停止状态,如果不是就调 用 request.begin(); 执行。??
//这里对当前 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);
}
}
3.2、RequestManager#runRequest->request#begin
- Request 的实现类是 SingleRequest
`@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));`
`}`
`}`
3.3 SingleRequest#onsizeReady->engine#load
- 终于到了engine#load
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(),
load:
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.isScaleOnlyOrNoTransform(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getUseAnimationPool(),
requestOptions.getOnlyRetrieveFromCache(),
this,
callbackExecutor);
3.3、engine#load->Engine
- 先构建请求或者缓存KEY
- 根据KEY找内存缓存、活动缓存,如果有就调用onResourceReady回调表示数据准备好了
- 如果没有找到就通过EngineJob.START
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点:
-
先构建请求或者缓存 KEY ;
-
根据 KEY 从内存缓存中查找对应的资源数据(ActiveResources(活动缓存,内部
是一个 Map 用弱引用持有),LruResourceCache),如果有就回调 对应监听的
onResourceReady 表示数据准备好了。
-
从执行缓存中查找对应 key 的任务
-
如果找到了,就说明已经正在执行了,不用重复执行。
-
没有找到,通过 EngineJob.start 开启一个新的请求任务执行。
同学们下面我们就来看下 engineJob.start 具体执行逻辑:
3.4、engineJob#start->executor#execute(decodeJob);
- 通过 DecodeJob 源码得知,它是实现的 Runnable 接口,这里 GlideExecutor 线程池开始执行,就会启动 DecodeJob 的 run 函数,我们跟踪 run 的实现:
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
//拿到 Glide 执行的线程池
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
//开始执行
executor.execute(decodeJob);
}
3.5、DecodeJob#RUN
- 核心走到runWrapped
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) {
.....//一些错误回调
}
}
3.5.1、runWrapped
- //获取资源状态
- stage = getNextStage(Stage.INITIALIZE);
- //根据当前资源状态,获取资源执行器 currentGenerator = getNextGenerator();
- //执行
- runGenerators();
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);
}
}
3.5.2、runGenerators
- 调用 DataFetcherGenerator.startNext() 判断是否是属于开始执行的任 务
- Stage.RESOURCE_CACHE【状态标记】 ---- 从磁盘中获取缓存的资源数据【作用】 -
- ResourceCacheGenerator【执行器】
- Stage.DATA_CACHE【状态标记】 ---- 从磁盘中获取缓存的源数据【作用】
- DataCacheGenerator【执行器】 Stage.SOURCE【状态标记】 --- 一次新的请求任务 --- SourceGenerator【执行器】
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
//判断是否取消,是否开始
//调用 DataFetcherGenerator.startNext() 判断是否是属于开始执行的任
务
while (!isCancelled && currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
....
}
3.5.3、currentGenerator#startNext->DataCacheGenerator
//获取一个 ModelLoad 加载器
loadData = helper.getLoadData().get(loadDataListIndex++);
//使用加载器中的 fetcher 根据优先级加载数据loadData.fetcher.loadData(helper.getPriority(), this);
@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;
}
3.5.3.1、helper.getLoadData()
3.6、DataCacheGenerator 下helper.getLoadData()
//开始构建加载器
modelLoader.buildLoadData(model, width, height,
options);
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;
}
3.6.1、😆modelLoader#buildLoadData ->modelLoader 也就是HttpGlideUrlLoader 返回了loadData
@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);
// 【同学们注意:之前有开发者看了一周Glide源码,也找不到网络请求的地方,我
们现在就已经找到了,很伟大了,可以给自己鼓掌】
return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
}
3.6.2、loadData#fetch#loadData->HttpUrlFetcher->通过callback.onDataReady(result)回到DataCahceGenerator
//http 请求,返回一个 InputStream 输入流
InputStream result =
@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 {
...
}
}
3.6.2.1、loadDataWithRedirects
- HttpURLConnection 作为 Glide 底层成网络请求的。请求成功之后直接返回的是一个输入流,最后会通过 onDataReady.回调到SourceGenerator
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);
}
...//抛的异常我们暂时先不管
}
3.6.3、SourceGenerator#onDataReady
@Override
public void onDataReady(Object data) {
DiskCacheStrategy diskCacheStrategy =
helper.getDiskCacheStrategy();
if (data != null &&
diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource(
))) {
dataToCache = data;
// 😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄 ResourceCallback cb
cb.reschedule();
} else {
//这里会有 else 因为我们没有配置缓存
cb.onDataFetcherReady(loadData.sourceKey, data,
loadData.fetcher,
loadData.fetcher.getDataSource(), originalKey);
}
}
3.6.4、DataCacheGenerator#cb.onDataFetcherReady(也就是 RCallback ) 然后通过callback回到->DecodeJob
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();
}
}
3.7、DecodeJob#decodeFromData 解码->LoadPath
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.load 方法中 ,接下来看下 LoadPath.load 方法的具体逻辑操作:
//获取当前数据类的解析器 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();
}
}
3.7.1、path.load
- 为了解析数据首先构建一个 LoadPath, 然后创建一个InputStreamRewinder 类型的 DataRewinder, 最终将数据解析的操作放到了LoadPath.load 方法中 ,接下来看下 LoadPath.load 方法的具体逻辑操作
public Resource<Transcode> load(DataRewinder<Data> rewinder,
@NonNull Options options, int width,
int height, DecodePath.DecodeCallback<ResourceType>
decodeCallback) throws GlideException {
try {
return loadWithExceptionList(rewinder, options, width,
height, decodeCallback, throwables);
} finally {
listPool.release(throwables);
}
}
private Resource<Transcode>
loadWithExceptionList(DataRewinder<Data> rewinder,
@NonNull Options options,
int width, int height,
DecodePath.DecodeCallback<ResourceType> decodeCallback,
List<Throwable> exceptions) throws GlideException {
Resource<Transcode> result = null;
//遍历内部存储的 DecodePath 集合,通过他们来解析数据
for (int i = 0, size = decodePaths.size(); i < size; i++) {
DecodePath<Data, ResourceType, Transcode> path =
decodePaths.get(i);
try {
//这里才是真正解析数据的地方
result = path.decode(rewinder, width, height, options,
decodeCallback);
} catch (GlideException e) {
...
}
...
return result;
}
3.8、LoadPath#path.decode 转码的地方
public Resource<Transcode> decode(DataRewinder<DataType>
rewinder, int width, int height,
@NonNull Options options, DecodeCallback<ResourceType>
callback) throws GlideException {
//调用 decodeResourec 将数据解析成中间资源
Resource<ResourceType> decoded = decodeResource(rewinder,
width, height, options);
//解析完数据回调出去
Resource<ResourceType> transformed =
callback.onResourceDecoded(decoded);
//转换资源为目标资源
return transcoder.transcode(transformed, options);
}
3.9、DecodePath#DecodeResource
- 第一大步:deResource 将源数据解析成资源(源数据: InputStream, 中间产物:Bitmap)
- 第二大步:调用 DecodeCallback.onResourceDecoded 处理资源
- 第三大步:调用 ResourceTranscoder.transcode 将资源转为目标资源(目标资源类型: Drawable)
@NonNull
private Resource<ResourceType>
decodeResource(DataRewinder<DataType> rewinder, int width,
int height, @NonNull Options options) throws GlideException
{
...
try {
return decodeResourceWithList(rewinder, width, height,
options, exceptions);
} finally {
...
}
}
@NonNull
private Resource<ResourceType>
decodeResourceWithList(DataRewinder<DataType> rewinder, int
width,
int height, @NonNull Options options, List<Throwable>
exceptions) throws GlideException {
Resource<ResourceType> result = null;
//noinspection ForLoopReplaceableByForEach to improve perf
for (int i = 0, size = decoders.size(); i < size; i++) {
ResourceDecoder<DataType, ResourceType> decoder =
decoders.get(i);
try {
DataType data = rewinder.rewindAndGet();
if (decoder.handles(data, options)) {
data = rewinder.rewindAndGet();
// 调用 ResourceDecoder.decode 解析数据
result = decoder.decode(data, width, height, options);
}
} catch (IOException | RuntimeException | OutOfMemoryError
e) {
...
}
return result;
}
3.9.1、decode#decode
@Override
public Resource<Bitmap> decode(@NonNull InputStream source, int
width, int height,
@NonNull Options options)
throws IOException {
// Use to fix the mark limit to avoid allocating buffers that
fit entire images.
final RecyclableBufferedInputStream bufferedStream;
final boolean ownsBufferedStream;
....
try {
// 根据请求配置来对数据进行采样压缩,获取一个 Resource<Bitmap>
return downsampler.decode(invalidatingStream, width,
height, options, callbacks);
} finally {
....
}
}
3.10、StreamBitmapDecoder#downsampler.decode
StreamBitmapDecoder
public Resource<Transcode> decode(DataRewinder<DataType>
rewinder, int width, int height,
@NonNull Options options, DecodeCallback<ResourceType>
callback) throws GlideException {
//第一步: 调用 decodeResourec 将数据解析成中间资源 Bitmap
Resource<ResourceType> decoded = decodeResource(rewinder,
width, height, options);
//第二步: 解析完数据回调出去
Resource<ResourceType> transformed =
callback.onResourceDecoded(decoded);
//第三步: 转换资源为目标资源 Bitmap to Drawable
return transcoder.transcode(transformed, options);
}
3.10.1、返回 给DecodePath
callback.onResourceDecoded->DecodeJob