Glide 源码分析之三 into
前言
在前两篇中,我们分析完了 with() 和 load() 方法:
Glide 分析之一 with
Glide 分析之二 load
接下来,我们将通过 load() 方法返回的 DrawableTypeRequest 对象,继续分析 into(imageView) 的过程。
本篇的阅读难度会比前两篇大很多,如果只关心流程,把主线部分看完就可以了,了解更多细节可以继续看支线内容。
为了方便阅读,文章中使用了锚点和支线关键字,可以使用浏览器搜索功能进行快速跳转。
into
DrawableTypeRequest 的 into() 方法只是调用了父类 GenericRequestBuilder 的 into() 方法:
public Target<TranscodeType> into(ImageView view) {
Util.assertMainThread();
if (view == null) {
throw new IllegalArgumentException("You must pass in a non null View");
}
if (!isTransformationSet && view.getScaleType() != null) {
switch (view.getScaleType()) {
case CENTER_CROP:
applyCenterCrop();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
applyFitCenter();
break;
//$CASES-OMITTED$
default:
// Do nothing.
}
}
return into(glide.buildImageViewTarget(view, transcodeClass));
}
transform 的逻辑先不分析,只关注最后一行代码。
其中 transcodeClass 为 GlideDrawable.class(见:支线1),glide.buildImageViewTarget() 方法返回了 GlideDrawableImageViewTarget 对象(见:支线2)(锚点1),然后传入 into() 方法中:
public <Y extends Target<TranscodeType>> Y into(Y target) {
Util.assertMainThread();
if (target == null) {
throw new IllegalArgumentException("You must pass in a non null Target");
}
if (!isModelSet) {
throw new IllegalArgumentException("You must first set a model (try #load())");
}
Request previous = target.getRequest();
if (previous != null) {
previous.clear();
requestTracker.removeRequest(previous);
previous.recycle();
}
Request request = buildRequest(target);
target.setRequest(request);
lifecycle.addListener(target);
requestTracker.runRequest(request);
return target;
}
忽略判断只看主要逻辑,buildRequest() 方法返回了 GenericRequest 对象(见:支线3),之后执行了 requestTracker.runRequest() 方法:
public void runRequest(Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
pendingRequests.add(request);
}
}
不考虑暂停的情况,直接看 GenericRequest 对象的 begin() 方法:
public void begin() {
···
if (model == null) {
onException(null);
return;
}
status = GenericRequest.Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {(锚点2)
onSizeReady(overrideWidth, overrideHeight);
} else {
target.getSize(this);
}
if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
··· 省略log
}
锚点2处,如果之前通过 override(int width, int height) 方法设置过宽高,就会走 onSizeReady() 方法,否则走
target.getSize() 方法。这里的 target 为 GlideDrawableImageViewTarget 对象(见:锚点1),它的 getSize() 方法在父类 ViewTarget 中:
public void getSize(SizeReadyCallback cb) {
sizeDeterminer.getSize(cb);
}
SizeDeterminer 是 ViewTarget 的内部静态类,它的 getSize() 方法会根据 ImageView 的 layout_width 和 layout_height 计算图片的宽高,获得宽高后会继续调用 onSizeReady() 方法:
public void onSizeReady(int width, int height) {
··· 省略log
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;
width = Math.round(sizeMultiplier * width);
height = Math.round(sizeMultiplier * height);
ModelLoader<A, T> modelLoader = loadProvider.getModelLoader();
final DataFetcher<T> dataFetcher = modelLoader.getResourceFetcher(model, width, height);
if (dataFetcher == null) {
onException(new Exception("Failed to load model: \'" + model + "\'"));
return;
}
ResourceTranscoder<Z, R> transcoder = loadProvider.getTranscoder();
··· 省略log
loadedFromMemoryCache = true;
loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
priority, isMemoryCacheable, diskCacheStrategy, this);
loadedFromMemoryCache = resource != null;
··· 省略log
}
其中:
loadProvider 为 FixedLoadProvider 对象(见:支线4)。
modelLoader 为 ImageVideoModelLoader 对象(见:支线5)。
transcoder 为 GifBitmapWrapperDrawableTranscoder 对象(见:支线5)。
dataFetcher 为 ImageVideoFetcher 对象(见:支线6)(锚点3)。
然后传入 engine.load() 方法中:
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
Util.assertMainThread();
···
final String id = fetcher.getId();
EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
transcoder, loadProvider.getSourceEncoder());
··· 省略缓存逻辑
EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
transcoder, diskCacheProvider, diskCacheStrategy, priority);
EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
jobs.put(key, engineJob);
engineJob.addCallback(cb);(锚点4)
engineJob.start(runnable);
···
return new LoadStatus(cb, engineJob);
}
可以看到创建了一个EngineRunnable 对象,并由 EngineJob 对象执行,看一下 EngineRunnable 的 run() 方法:
public void run() {
if (isCancelled) {
return;
}
Exception exception = null;
Resource<?> resource = null;
try {
resource = decode();(锚点5)
} catch (Exception e) {
··· 省略log
exception = e;
}
if (isCancelled) {
if (resource != null) {
resource.recycle();
}
return;
}
if (resource == null) {
onLoadFailed(exception);
} else {
onLoadComplete(resource);
}
}
方法很清晰,主要工作在 decode() 方法中:
private Resource<?> decode() throws Exception {
if (isDecodingFromCache()) {
return decodeFromCache();
} else {
return decodeFromSource();
}
}
不考虑缓存的情况,看 decodeFromSource() 方法:
private Resource<?> decodeFromSource() throws Exception {
return decodeJob.decodeFromSource();
}
这里调用了 DecodeJob 对象的 decodeFromSource() 方法:
public Resource<Z> decodeFromSource() throws Exception {
Resource<T> decoded = decodeSource();
return transformEncodeAndTranscode(decoded);
}
private Resource<T> decodeSource() throws Exception {
Resource<T> decoded = null;
try {
···
final A data = fetcher.loadData(priority);
··· 省略log
if (isCancelled) {
return null;
}
decoded = decodeFromSourceData(data);
} finally {
fetcher.cleanup();
}
return decoded;
}
fetcher 为 ImageVideoFetcher 对象(见:锚点3),它的 loadData() 方法:
public ImageVideoWrapper loadData(Priority priority) throws Exception {
InputStream is = null;
if (streamFetcher != null) {
try {
is = streamFetcher.loadData(priority);
} catch (Exception e) {
··· 省略log
if (fileDescriptorFetcher == null) {
throw e;
}
}
}
ParcelFileDescriptor fileDescriptor = null;
if (fileDescriptorFetcher != null) {
try {
fileDescriptor = fileDescriptorFetcher.loadData(priority);
} catch (Exception e) {
··· 省略log
if (is == null) {
throw e;
}
}
}
return new ImageVideoWrapper(is, fileDescriptor);(锚点6)
}
streamFetcher 就是创建 ImageVideoFetcher 对象时传入的 StreamLocalUriFetcher 对象(见:锚点12),它的 loadData() 方法在父类 LocalUriFetcher 中:
public final T loadData(Priority priority) throws Exception {
ContentResolver contentResolver = context.getContentResolver();
data = loadResource(uri, contentResolver);
return data;
}
loadResource() 方法由子类 StreamLocalUriFetcher 实现:
protected InputStream loadResource(Uri uri, ContentResolver contentResolver) throws FileNotFoundException {
return contentResolver.openInputStream(uri);
}
现在我们拿到了想要加载文件的输入流,创建 ImageVideoWrapper 对象(见:锚点6),然后传递给 decodeFromSourceData() 方法:
private Resource<T> decodeFromSourceData(A data) throws IOException {
final Resource<T> decoded;
··· 省略缓存
decoded = loadProvider.getSourceDecoder().decode(data, width, height);
···
return decoded;
}
loadProvider.getSourceDecoder() 返回了 GifBitmapWrapperResourceDecoder 对象(见:支线8),它的 decode() 方法:
public Resource<GifBitmapWrapper> decode(ImageVideoWrapper source, int width, int height) throws IOException {
ByteArrayPool pool = ByteArrayPool.get();
byte[] tempBytes = pool.getBytes();
GifBitmapWrapper wrapper = null;
try {
wrapper = decode(source, width, height, tempBytes);
} finally {
pool.releaseBytes(tempBytes);
}
return wrapper != null ? new GifBitmapWrapperResource(wrapper) : null;
}
private GifBitmapWrapper decode(ImageVideoWrapper source, int width, int height, byte[] bytes) throws IOException {
final GifBitmapWrapper result;
if (source.getStream() != null) {
result = decodeStream(source, width, height, bytes);
} else {
result = decodeBitmapWrapper(source, width, height);
}
return result;
}
private GifBitmapWrapper decodeStream(ImageVideoWrapper source, int width, int height, byte[] bytes)
throws IOException {
InputStream bis = streamFactory.build(source.getStream(), bytes);
bis.mark(MARK_LIMIT_BYTES);
ImageHeaderParser.ImageType type = parser.parse(bis);
bis.reset();
GifBitmapWrapper result = null;
if (type == ImageHeaderParser.ImageType.GIF) {
result = decodeGifWrapper(bis, width, height);
}
// Decoding the gif may fail even if the type matches.
if (result == null) {
ImageVideoWrapper forBitmapDecoder = new ImageVideoWrapper(bis, source.getFileDescriptor());
result = decodeBitmapWrapper(forBitmapDecoder, width, height);
}
return result;
}
private GifBitmapWrapper decodeBitmapWrapper(ImageVideoWrapper toDecode, int width, int height) throws IOException {
GifBitmapWrapper result = null;
Resource<Bitmap> bitmapResource = bitmapDecoder.decode(toDecode, width, height);
if (bitmapResource != null) {
result = new GifBitmapWrapper(bitmapResource, null);
}
return result;
}
在 decodeBitmapWrapper() 方法中,bitmapDecoder 为 ImageVideoBitmapDecoder 对象(见:支线9),它的 decode() 方法:
public Resource<Bitmap> decode(ImageVideoWrapper source, int width, int height) throws IOException {
Resource<Bitmap> result = null;
InputStream is = source.getStream();
if (is != null) {
try {
result = streamDecoder.decode(is, width, height);
} catch (IOException e) {
··· 省略log
}
}
if (result == null) {
ParcelFileDescriptor fileDescriptor = source.getFileDescriptor();
if (fileDescriptor != null) {
result = fileDescriptorDecoder.decode(fileDescriptor, width, height);
}
}
return result;
}
因为我们之前传入了 InputStream,所以会执行 streamDecoder.decode() 方法,streamDecoder 为 StreamBitmapDecoder对象(见:支线12),它的 decode() 方法:
public Resource<Bitmap> decode(InputStream source, int width, int height) {
Bitmap bitmap = downsampler.decode(source, bitmapPool, width, height, decodeFormat);
return BitmapResource.obtain(bitmap, bitmapPool);
}
继续看 downsampler.decode() 方法:
public Bitmap decode(InputStream is, BitmapPool pool, int outWidth, int outHeight, DecodeFormat decodeFormat) {
final ByteArrayPool byteArrayPool = ByteArrayPool.get();
final byte[] bytesForOptions = byteArrayPool.getBytes();
final byte[] bytesForStream = byteArrayPool.getBytes();
final BitmapFactory.Options options = getDefaultOptions();
RecyclableBufferedInputStream bufferedStream = new RecyclableBufferedInputStream(
is, bytesForStream);
ExceptionCatchingInputStream exceptionStream =
ExceptionCatchingInputStream.obtain(bufferedStream);
MarkEnforcingInputStream invalidatingStream = new MarkEnforcingInputStream(exceptionStream);
try {
exceptionStream.mark(MARK_POSITION);
int orientation = 0;
try {
orientation = new ImageHeaderParser(exceptionStream).getOrientation();
} catch (IOException e) {
} finally {
try {
exceptionStream.reset();
} catch (IOException e) {
}
}
options.inTempStorage = bytesForOptions;
final int[] inDimens = getDimensions(invalidatingStream, bufferedStream, options);
final int inWidth = inDimens[0];
final int inHeight = inDimens[1];
final int degreesToRotate = TransformationUtils.getExifOrientationDegrees(orientation);
final int sampleSize = getRoundedSampleSize(degreesToRotate, inWidth, inHeight, outWidth, outHeight);
final Bitmap downsampled =
downsampleWithSize(invalidatingStream, bufferedStream, options, pool, inWidth, inHeight, sampleSize,
decodeFormat);
final Exception streamException = exceptionStream.getException();
if (streamException != null) {
throw new RuntimeException(streamException);
}
Bitmap rotated = null;
if (downsampled != null) {
rotated = TransformationUtils.rotateImageExif(downsampled, pool, orientation);
if (!downsampled.equals(rotated) && !pool.put(downsampled)) {
downsampled.recycle();
}
}
return rotated;
} finally {
byteArrayPool.releaseBytes(bytesForOptions);
byteArrayPool.releaseBytes(bytesForStream);
exceptionStream.release();
releaseOptions(options);
}
}
看到 BitmapFactory.Options 变量和 sampleSize 变量就知道,本篇分析想要找的问题,终于在这里得到了答案。
其中详细的处理过程都大同小异,不再赘述。
这个方法最终返回了 Bitmap 对象。
至此图片解析的过程就结束了,接下来的流程就是传递 Bitmap 到上层传递并最终加载到 ImageView 中。
BitmapResource.obtain() 方法将 Bitmap 对象包装成 BitmapResource 对象,返回给 ImageVideoBitmapDecoder,然后继续返回到 GifBitmapWrapperResourceDecoder 的 decodeStream() 方法中,包装为 GifBitmapWrapper 对象,返回给 DecodeJob 对象的 decodeFromSource() 方法接下来会调用 transformEncodeAndTranscode() 方法:
private Resource<Z> transformEncodeAndTranscode(Resource<T> decoded) {
Resource<T> transformed = transform(decoded);
···
Resource<Z> result = transcode(transformed);
return result;
}
transform() 方法将传入的参数原样返回(见:支线14),然后传递给 transcode() 方法:
private Resource<Z> transcode(Resource<T> transformed) {
if (transformed == null) {
return null;
}
return transcoder.transcode(transformed);
}
transcoder 为 GifBitmapWrapperDrawableTranscoder 对象(见:锚点9),它的 transcode() 方法:
public Resource<GlideDrawable> transcode(Resource<GifBitmapWrapper> toTranscode) {
GifBitmapWrapper gifBitmap = toTranscode.get();
Resource<Bitmap> bitmapResource = gifBitmap.getBitmapResource();
final Resource<? extends GlideDrawable> result;
if (bitmapResource != null) {
result = bitmapDrawableResourceTranscoder.transcode(bitmapResource);
} else {
result = gifBitmap.getGifResource();
}
// This is unchecked but always safe, anything that extends a Drawable can be safely cast to a Drawable.
return (Resource<GlideDrawable>) result;
}
其中 bitmapDrawableResourceTranscoder 为 GlideBitmapDrawableTranscoder 对象(见:锚点10),看它的 transcode() 方法:
public Resource<GlideBitmapDrawable> transcode(Resource<Bitmap> toTranscode) {
GlideBitmapDrawable drawable = new GlideBitmapDrawable(resources, toTranscode.get());
return new GlideBitmapDrawableResource(drawable, bitmapPool);
}
返回了 GlideBitmapDrawableResource 对象,它实现了 Resource<GlideBitmapDrawable> 接口。
最终返回到 EngineRunnable 的 run() 方法处(见:锚点5),之后执行 onLoadComplete() 方法:
private void onLoadComplete(Resource resource) {
manager.onResourceReady(resource);
}
manager 为 EngineRunnable 创建时传入的 EngineJob 对象,它的 onResourceReady() 方法:
public void onResourceReady(final Resource<?> resource) {
this.resource = resource;
MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}
MAIN_THREAD_HANDLER 的 Callback 实现:
private static final Handler MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper(), new MainThreadCallback());
private static class MainThreadCallback implements Handler.Callback {
@Override
public boolean handleMessage(Message message) {
if (MSG_COMPLETE == message.what || MSG_EXCEPTION == message.what) {
EngineJob job = (EngineJob) message.obj;
if (MSG_COMPLETE == message.what) {
job.handleResultOnMainThread();
} else {
job.handleExceptionOnMainThread();
}
return true;
}
return false;
}
}
这里执行了 job.handleResultOnMainThread() 方法:
private void handleResultOnMainThread() {
if (isCancelled) {
resource.recycle();
return;
} else if (cbs.isEmpty()) {
throw new IllegalStateException("Received a resource without any callbacks to notify");
}
engineResource = engineResourceFactory.build(resource, isCacheable);
hasResource = true;
engineResource.acquire();
listener.onEngineJobComplete(key, engineResource);
for (ResourceCallback cb : cbs) {
if (!isInIgnoredCallbacks(cb)) {
engineResource.acquire();
cb.onResourceReady(engineResource);
}
}
// Our request is complete, so we can release the resource.
engineResource.release();
}
通过 engineResourceFactory.build() 方法将 resource 封装进 EngineResource 对象,然后调用了 ResourceCallback 的 onResourceReady() 方法传递出去。
GenericRequest 实现了 ResourceCallback 接口(见:支线15),看它的 onResourceReady() 方法:
public void onResourceReady(Resource<?> resource) {
··· 省略检查参数合法性的步骤
Object received = resource.get();
··· 省略检查参数合法性的步骤
if (!canSetResource()) {
releaseResource(resource);
// We can't set the status to complete before asking canSetResource().
status = GenericRequest.Status.COMPLETE;
return;
}
onResourceReady(resource, (R) received);
}
private void onResourceReady(Resource<?> resource, R result) {
// We must call isFirstReadyResource before setting status.
boolean isFirstResource = isFirstReadyResource();
status = GenericRequest.Status.COMPLETE;
this.resource = resource;
if (requestListener == null || !requestListener.onResourceReady(result, model, target, loadedFromMemoryCache,
isFirstResource)) {
GlideAnimation<R> animation = animationFactory.build(loadedFromMemoryCache, isFirstResource);
target.onResourceReady(result, animation);
}
notifyLoadSuccess();
··· 省略log
}
创建了一个动画和 result 作为参数 target.onResourceReady() 方法。
target 为 glide.buildImageViewTarget() 方法创建的 GlideDrawableImageViewTarget 对象(见:锚点1),
看它的 onResourceReady() 方法:
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
if (!resource.isAnimated()) {
float viewRatio = view.getWidth() / (float) view.getHeight();
float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN
&& Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
resource = new SquaringDrawable(resource, view.getWidth());
}
}
super.onResourceReady(resource, animation);
this.resource = resource;
resource.setLoopCount(maxLoopCount);
resource.start();
}
这里又调用了父类的 onResourceReady() 方法:
public void onResourceReady(Z resource, GlideAnimation<? super Z> glideAnimation) {
if (glideAnimation == null || !glideAnimation.animate(resource, this)) {
setResource(resource);
}
}
其中,glideAnimation.animate() 方法执行了图片第一次显示时的淡入动画。
setResource() 方法由子类实现:
protected void setResource(GlideDrawable resource) {
view.setImageDrawable(resource);
}
这个 view 就是 into() 方法中传入的 ImageView .
至此,图片终于显示出来了。
通过Glide.with(this).load(resourceId).into(imageView)
这行代码,对 Glide 执行流程的分析到此也就结束了。
谢谢大家。
支线1:transcodeClass 是什么
transcodeClass 在 GenericRequestBuilder 中是 final 修饰的成员变量,在 GenericRequestBuilder 构造函数中初始化,在第二篇 load() 方法创建 DrawableTypeRequest 对象时传入,看一下 DrawableTypeRequest 的构造方法:
DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
super(context, modelClass,
buildProvider(glide, streamModelLoader, fileDescriptorModelLoader,
GifBitmapWrapper.class, GlideDrawable.class, null),
glide, requestTracker, lifecycle);
this.streamModelLoader = streamModelLoader;
this.fileDescriptorModelLoader = fileDescriptorModelLoader;
this.optionsApplier = optionsApplier;
}
继续看到它调用的父类构造方法:
DrawableRequestBuilder(Context context, Class<ModelType> modelClass,
LoadProvider<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable> loadProvider, Glide glide,
RequestTracker requestTracker, Lifecycle lifecycle) {
super(context, modelClass, loadProvider, GlideDrawable.class, glide, requestTracker, lifecycle);
// Default to animating.
crossFade();
}
注意 GlideDrawable.class,这就是传递给父类 GenericRequestBuilder 中 transcodeClass 参数的值(锚点7)。
支线2:buildImageViewTarget() 方法返回值
<R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}
跟进看buildTarget()方法:
public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
if (GlideDrawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new GlideDrawableImageViewTarget(view);
} else if (Bitmap.class.equals(clazz)) {
return (Target<Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException("Unhandled class: " + clazz
+ ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
transcodedClass 为 GlideDrawable.class(见:锚点7),所以返回了 GlideDrawableImageViewTarget 对象。
支线3:buildRequest(target) 方法返回值
Request 是一个接口,来看看 buildRequest() 方法返回了哪个实现类:
private Request buildRequest(Target<TranscodeType> target) {
···
return buildRequestRecursive(target, null);
}
private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
if (thumbnailRequestBuilder != null) {
··· 忽略略缩图逻辑
} else if (thumbSizeMultiplier != null) {
··· 忽略略缩图逻辑
} else {
// Base case: no thumbnail.
return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
}
}
private Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
RequestCoordinator requestCoordinator) {
return GenericRequest.obtain(
loadProvider,
model,
signature,
context,
priority,
target,
sizeMultiplier,
placeholderDrawable,
placeholderId,
errorPlaceholder,
errorId,
fallbackDrawable,
fallbackResource,
requestListener,
requestCoordinator,
glide.getEngine(),
transformation,
transcodeClass,
isCacheable,
animationFactory,
overrideWidth,
overrideHeight,
diskCacheStrategy);
}
GenericRequest.obtain() 方法创建了 GenericRequest 对象,所以 buildRequest() 方法最终返回了 GenericRequest 对象。
支线4:loadProvider 是什么
loadProvider 在 DrawableTypeRequest 的构造方法创建:
DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
super(context, modelClass,
buildProvider(glide, streamModelLoader, fileDescriptorModelLoader,
GifBitmapWrapper.class, GlideDrawable.class, null),
glide, requestTracker, lifecycle);
this.streamModelLoader = streamModelLoader;
this.fileDescriptorModelLoader = fileDescriptorModelLoader;
this.optionsApplier = optionsApplier;
}
DrawableTypeRequest 通过 buildProvider() 方法创建了 FixedLoadProvider 对象:
private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(Glide glide,
ModelLoader<A, InputStream> streamModelLoader,
ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, Class<Z> resourceClass,
Class<R> transcodedClass, ResourceTranscoder<Z, R> transcoder) {
···
return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
}
所以 loadProvider 就是 FixedLoadProvider 对象。
支线5:创建 FixedLoadProvider 对象时的三个参数是什么
private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(Glide glide,
ModelLoader<A, InputStream> streamModelLoader,
ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, Class<Z> resourceClass,
Class<R> transcodedClass, ResourceTranscoder<Z, R> transcoder) {
···
if (transcoder == null) {
transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
}
DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
resourceClass);
ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
fileDescriptorModelLoader);
return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
}
可以看到 modelLoader 是 ImageVideoModelLoader 对象,而创建时放入的 streamModelLoader 是 StreamResourceLoader 对象(锚点8),fileDescriptorModelLoader 是 FileDescriptorResourceLoader 对象(第二篇最后分析过)。
transcoder 来自 glide.buildTranscoder() 方法:
<Z, R> ResourceTranscoder<Z, R> buildTranscoder(Class<Z> decodedClass, Class<R> transcodedClass) {
return transcoderRegistry.get(decodedClass, transcodedClass);
}
decodedClass 在 DrawableTypeRequest 构造方法中传递过来,值为 GifBitmapWrapper.class.
transcodedClass 就是上边分析过的 GlideDrawable.class(见:锚点7)。
transcoderRegistry 在 Glide 的构造方法中放入数据:
transcoderRegistry.register(
GifBitmapWrapper.class,
GlideDrawable.class,
new GifBitmapWrapperDrawableTranscoder(new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));
所以 transcoder 就是 buildTranscoder() 方法返回的 GifBitmapWrapperDrawableTranscoder 对象(锚点9)。
创建 GifBitmapWrapperDrawableTranscoder 对象时,放入了 GlideBitmapDrawableTranscoder 对象(锚点10)。
glide.buildDataProvider() 方法同理,它返回了 ImageVideoGifDrawableLoadProvider 对象(锚点11)。
所以传入 FixedLoadProvider 构造方法的三个参数分别为:ImageVideoModelLoader 对象,GifBitmapWrapperDrawableTranscoder 对象,ImageVideoGifDrawableLoadProvider 对象。
支线6 modelLoader.getResourceFetcher() 方法返回值
public DataFetcher<ImageVideoWrapper> getResourceFetcher(A model, int width, int height) {
DataFetcher<InputStream> streamFetcher = null;
if (streamLoader != null) {
streamFetcher = streamLoader.getResourceFetcher(model, width, height);
}
DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher = null;
if (fileDescriptorLoader != null) {
fileDescriptorFetcher = fileDescriptorLoader.getResourceFetcher(model, width, height);
}
if (streamFetcher != null || fileDescriptorFetcher != null) {
return new ImageVideoFetcher(streamFetcher, fileDescriptorFetcher);
} else {
return null;
}
}
其中 streamLoader 为 StreamResourceLoader(见:锚点8),它的 getResourceFetcher() 方法在父类 ResourceLoader 中:
public DataFetcher<T> getResourceFetcher(Integer model, int width, int height) {
Uri uri = null;
try {
uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
+ resources.getResourcePackageName(model) + '/'
+ resources.getResourceTypeName(model) + '/'
+ resources.getResourceEntryName(model));
} catch (Resources.NotFoundException e) {
··· 省略log
}
if (uri != null) {
return uriLoader.getResourceFetcher(uri, width, height);
} else {
return null;
}
}
uriLoader 为 StreamUriLoader 对象(见:支线7),它的 getResourceFetcher 方法在父类 UriLoader 中:
public final DataFetcher<T> getResourceFetcher(Uri model, int width, int height) {
final String scheme = model.getScheme();
DataFetcher<T> result = null;
if (isLocalUri(scheme)) {
if (AssetUriParser.isAssetUri(model)) {
String path = AssetUriParser.toAssetPath(model);
result = getAssetPathFetcher(context, path);
} else {
result = getLocalUriFetcher(context, model);
}
} else if (urlLoader != null && ("http".equals(scheme) || "https".equals(scheme))) {
result = urlLoader.getResourceFetcher(new GlideUrl(model.toString()), width, height);
}
return result;
}
private static boolean isLocalUri(String scheme) {
return ContentResolver.SCHEME_FILE.equals(scheme)
|| ContentResolver.SCHEME_CONTENT.equals(scheme)
|| ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme);
}
public static boolean isAssetUri(Uri uri) {
return ContentResolver.SCHEME_FILE.equals(uri.getScheme()) && !uri.getPathSegments().isEmpty()
&& ASSET_PATH_SEGMENT.equals(uri.getPathSegments().get(0));
}
通过这两个方法的判断,最终会执行子类 StreamUriLoader 实现的 getLocalUriFetcher() 方法:
protected DataFetcher<InputStream> getLocalUriFetcher(Context context, Uri uri) {
return new StreamLocalUriFetcher(context, uri);
}
所以 streamLoader.getResourceFetcher() 返回了 StreamLocalUriFetcher 对象。
而 loadProvider 为之前传入的 FileDescriptorResourceLoader 对象,它的 getResourceFetcher() 方法同理,返回了 FileDescriptorLocalUriFetcher 对象。
最终创建 ImageVideoFetcher 对象并传入 StreamLocalUriFetcher对象(锚点12)和 FileDescriptorLocalUriFetcher 对象,最后返回。
支线7 uriLoader 是什么
uriLoader 为在 StreamResourceLoader 的父类 ResourceLoader 的构造方法中传入,查找 StreamResourceLoader 创建时传入的 uriLoader:
public ModelLoader<Integer, InputStream> build(Context context, GenericLoaderFactory factories) {
return new StreamResourceLoader(context, factories.buildModelLoader(Uri.class, InputStream.class));
}
查看 factories.buildModelLoader() 方法:
public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
···
final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
if (factory != null) {
result = factory.build(context, this);
···
} else {
···
}
return result;
}
又是出场很多次的 getFactory() 方法,直接在 Glide 构造方法中找到对应的 Factory 为 StreamUriLoader.Factory(),所以 uriLoader 为 StreamUriLoader 对象。
支线8:loadProvider.getSourceDecoder() 返回值
loadProvider 为 FixedLoadProvider 对象,它的 getSourceDecoder() 方法:
public ResourceDecoder<T, Z> getSourceDecoder() {
return dataLoadProvider.getSourceDecoder();
}
dataLoadProvider 为 ImageVideoGifDrawableLoadProvider 对象(见:锚点11),它的 sourceDecoder 为
GifBitmapWrapperResourceDecoder 对象:
public ImageVideoGifDrawableLoadProvider(DataLoadProvider<ImageVideoWrapper, Bitmap> bitmapProvider,
DataLoadProvider<InputStream, GifDrawable> gifProvider, BitmapPool bitmapPool) {
final GifBitmapWrapperResourceDecoder decoder = new GifBitmapWrapperResourceDecoder(
bitmapProvider.getSourceDecoder(),
gifProvider.getSourceDecoder(),
bitmapPool
);
···
sourceDecoder = decoder;
···
}
所以返回了GifBitmapWrapperResourceDecoder 对象。
支线9:bitmapDecoder 是什么
bitmapDecoder 在 GifBitmapWrapperResourceDecoder 创建时传入:
public GifBitmapWrapperResourceDecoder(ResourceDecoder<ImageVideoWrapper, Bitmap> bitmapDecoder,
ResourceDecoder<InputStream, GifDrawable> gifDecoder, BitmapPool bitmapPool) {
this(bitmapDecoder, gifDecoder, bitmapPool, DEFAULT_PARSER, DEFAULT_STREAM_FACTORY);
}
GifBitmapWrapperResourceDecoder 对象在 ImageVideoGifDrawableLoadProvider 的构造方法中创建:
public ImageVideoGifDrawableLoadProvider(DataLoadProvider<ImageVideoWrapper, Bitmap> bitmapProvider,
DataLoadProvider<InputStream, GifDrawable> gifProvider, BitmapPool bitmapPool) {
final GifBitmapWrapperResourceDecoder decoder = new GifBitmapWrapperResourceDecoder(
bitmapProvider.getSourceDecoder(),
gifProvider.getSourceDecoder(),
bitmapPool
);
···
}
bitmapProvider 为 ImageVideoDataLoadProvider 对象(见:支线10),它的 getSourceDecoder() 方法返回了 ImageVideoBitmapDecoder 对象(见:支线11)。
所以 bitmapDecoder 就是 ImageVideoBitmapDecoder 对象。
支线10:bitmapProvider 是什么
bitmapProvider 在 ImageVideoGifDrawableLoadProvider 的构造方法中传入,ImageVideoGifDrawableLoadProvider 对象在 Glide 构造方法中创建:
dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
new ImageVideoGifDrawableLoadProvider(imageVideoDataLoadProvider, gifDrawableLoadProvider, bitmapPool));
创建时使用的 imageVideoDataLoadProvider 对象也在 Glide 构造方法中创建:
ImageVideoDataLoadProvider imageVideoDataLoadProvider =
new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);
bitmapProvider 就是 ImageVideoDataLoadProvider 对象。
支线11:getSourceDecoder()方法返回值
getSourceDecoder() 方法直接返回了在构造方法中创建的成员变量 sourceDecoder:
public ImageVideoDataLoadProvider(DataLoadProvider<InputStream, Bitmap> streamBitmapProvider,
DataLoadProvider<ParcelFileDescriptor, Bitmap> fileDescriptorBitmapProvider) {
sourceDecoder = new ImageVideoBitmapDecoder(streamBitmapProvider.getSourceDecoder(),
fileDescriptorBitmapProvider.getSourceDecoder());
}
所以 getSourceDecoder() 方法返回了 ImageVideoBitmapDecoder 对象。
支线12:streamDecoder 是什么
streamDecoder 在 ImageVideoBitmapDecoder 的构造方法中传入,ImageVideoBitmapDecoder 对象在
ImageVideoDataLoadProvider 构造方法中创建:
public ImageVideoDataLoadProvider(DataLoadProvider<InputStream, Bitmap> streamBitmapProvider,
DataLoadProvider<ParcelFileDescriptor, Bitmap> fileDescriptorBitmapProvider) {
sourceDecoder = new ImageVideoBitmapDecoder(streamBitmapProvider.getSourceDecoder(),
fileDescriptorBitmapProvider.getSourceDecoder());
}
streamBitmapProvider 为 StreamBitmapDataLoadProvider 对象(见:支线13),它的 getSourceDecoder()
方法直接返回了在构造方法中创建的成员变量 decoder:
public StreamBitmapDataLoadProvider(BitmapPool bitmapPool, DecodeFormat decodeFormat) {
···
decoder = new StreamBitmapDecoder(bitmapPool, decodeFormat);
···
}
所以 streamDecoder 就是 StreamBitmapDecoder 对象。
支线13:streamBitmapProvider 是什么
streamBitmapProvider 在 ImageVideoDataLoadProvider 构造方法中传入,ImageVideoDataLoadProvider 对象和创建时使用的 streamBitmapLoadProvider 在 Glide 构造方法中创建:
ImageVideoDataLoadProvider imageVideoDataLoadProvider =
new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);
StreamBitmapDataLoadProvider streamBitmapLoadProvider =
new StreamBitmapDataLoadProvider(bitmapPool, decodeFormat);
所以 streamBitmapProvider 为 StreamBitmapDataLoadProvider 对象。
StreamBitmapDataLoadProvider 对象创建时传入了 bitmapPool,decodeFormat 参数。
这两个参数从 Glide 构造方法中传入,bitmapPool 如果没有设置过并且 Build.VERSION.SDK_INT 大于11,默认为 LruBitmapPool,decodeFormat 如果没有通过 API 设置过默认为 PREFER_RGB_565。
支线14:transform() 方法如何将传入的参数原样返回
private Resource<T> transform(Resource<T> decoded) {
if (decoded == null) {
return null;
}
Resource<T> transformed = transformation.transform(decoded, width, height);
if (!decoded.equals(transformed)) {
decoded.recycle();
}
return transformed;
}
transformation 来自于 GenericRequestBuilder 的成员变量:
private Transformation<ResourceType> transformation = UnitTransformation.get();
UnitTransformation.get() 方法获取了一个 UnitTransformation 对象,它的 transform() 方法直接返回了传递进来的参数:
public Resource<T> transform(Resource<T> resource, int outWidth, int outHeight) {
return resource;
}
支线15:谁实现了 ResourceCallback
ResourceCallback 在 EngineJob 的 addCallback() 方法中添加,engine 对象执行 load() 方法时会调用
engineJob.addCallback() 方法(见:锚点4)。
GenericRequest 中实现了 ResourceCallback 接口并在调用 engine.load() 方法时传递了 this 进去。
所以这里的 ResourceCallback 实现类就是 GenericRequest.