Glide 4.0+源码分析
- 总体分析
- 图片加载流程
- with
- getRetriever
- Glide.get()
- initializeGlide
- RequestManagerRetriever.get()
- Application
- Activity
- Fragment
- RequestManager
- 总结
- load
- asDrawable()
- load
- into
- into
- buildRequest
- buildThumbnailRequestRecursive
- obtainRequest
- begin
- onSizeReady
- load
- DecodeJob.run()
- runWrapped
- getNextStage & getNextGenerator
- runGenerators
- SourceGenerator.startNext()
- loadData
- onResponse
- onDataReady
- SourceGenerator.startNext
- DataCacheGenerator.startNext
- decodeFromRetrievedData
- notifyEncodeAndRelease
- EngineJob.onResourceReady
- EngineJob.notifyCallbacksOfResult
- CallResourceReady
- SingleRequest.onResourceReady
- DrawableImageViewTarget.setResource
- 总结
写过Glide的使用和一些注意事项了,这次简单分析下Glide的加载图片流程。
GlideApp.with(context)
.load(resId)
.into(imageView);
总体分析
整体框架可以看作以下几个部分:
- Glide 初始化系统,负责管理系统其他模块,比如:数据加载器、网络栈等。
- RequestManager 创建、初始化以及管理系统所有的Request。
- Engine 将资源加载请求放入执行线程池,加载完后返回主线程
- DataFetcher 从磁盘或者网络端加载数据
按照包的分类如下:
图片加载流程
还是从简单的加载图片开始:
String url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png";
GlideApp.with(context.getApplicationContext())
.load(url)
.into(imageView);
with
会走到Glide
里面的with
方法
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
会执行getRetriever(context).get(context)
返回一个RequestManager
对象。它是一个请求管理类。接着看getRetriever
方法。
还有很多重载方法,对应各种上下文:
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
@NonNull
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
/** @deprecated */
@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
@NonNull
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
getRetriever
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever();
}
有判空的处理,为null会判处异常,平时也会遇到的。然后调用Glide的get
方法:
Glide.get()
private static volatile Glide glide;
public static Glide get(@NonNull Context context) {
//很明显的单例模式
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
单例模式
很明显是一个单例,这个是DCL+volatile 单例,很严谨的单例。后面会走到一个initializeGlide
方法来创建glide的实例。
initializeGlide
构建者模式
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
//拿到application上下文
Context applicationContext = context.getApplicationContext();
//getAnnotationGeneratedGlideModules 是反射创建了GeneratedAppGlideModuleImpl类
//GeneratedAppGlideModuleImpl 是注解生成的类,4.0+版本特性,主要创建GeneratedRequestManagerFactory的工厂类
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
//清单文件的配置项,可以跳过
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set<Class<?>> excludedModuleClasses =
annotationGeneratedModule.getExcludedModuleClasses();
Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
while (iterator.hasNext()) {
com.bumptech.glide.module.GlideModule current = iterator.next();
if (!excludedModuleClasses.contains(current.getClass())) {
continue;
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
}
iterator.remove();
}
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
}
}
//以上是清单文件的配置项,可以跳过
//创建请求管理的工厂类,就是前面提到的GeneratedAppGlideModuleImpl 会调用new GeneratedRequestManagerFactory()创建
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory() : null;
builder.setRequestManagerFactory(factory);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
//构建参数 应用上下文 构建单例,也会创建RequestManagerRetriever实例,还会执行一些任务,还会创建engine类。先跳过
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(applicationContext, glide, glide.registry);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
//Glide实现了ComponentCallbacks2接口,实现了trimMemory接口,会根据内存被使用情况,清除一些缓存。
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
主要做了几个操作:获取注解生成的类、创建请求工厂类RequestManagerFactory
、获取清单文件的配置信息、添加ComponentCallbacks2
接口监听处理内存,最后生成Glide实例。
RequestManagerRetriever.get()
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
在返回return Glide.get(context).getRequestManagerRetriever()
这句代码中,getRequestManagerRetriever
就会返回RequestManagerRetriever对象,在联级调用RequestManagerRetriever.get()
方法。
由于with()
有很多重载方法,具体只看Application、activity和fragment的处理逻辑。
Application
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
if (this.applicationManager == null) {
synchronized(this) {
if (this.applicationManager == null) {
//获取前面创建的单例glide
Glide glide = Glide.get(context.getApplicationContext());
//获取build构建的RequestManagerFactory工厂类创建RequestManager。
this.applicationManager = this.factory.build(glide, new ApplicationLifecycle(), new EmptyRequestManagerTreeNode(), context.getApplicationContext());
}
}
}
return this.applicationManager;
}
工厂模式
这里就是用前面初始化方法创建的factory来创建一个RequestManager。
Activity
现在都是继承AppCompatActivity,而AppCompatActivity再继承FragmentActivity的,所以Activity另一个重载不在推荐了。
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
走的supportFragmentGet,跟下面supportFragmentGet一起看。因为自身是activity,传的是父级FragmentManager。isActivityVisible
就是返回当前activity是否finish。
Fragment
@NonNull
public RequestManager get(@NonNull Fragment fragment) {
Preconditions.checkNotNull(fragment.getActivity(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
}
}
走的supportFragmentGet,因为自身是fragment,传的是子级FragmentManager。
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
观察者模式ActivityFragmentLifecycle
有一个LifecycleListener的Set集合。相当于一个被观察者维护了一个观察者的集合。
看getSupportRequestManagerFragment()
方法,这里跟glide加载图片的生命周期有关。而SupportRequestManagerFragment
的生命周期会与传入的lifecycle进行绑定的,
然后也是调用factory去创建RequestManager
。
@NonNull
private RequestManager supportFragmentGet(@NonNull Context context, @NonNull androidx.fragment.app.FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
//去创建一个fragment 用来绑定生命周期
SupportRequestManagerFragment current = this.getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
//获取当前创建的fragment所持有的RequestManager
RequestManager requestManager = current.getRequestManager();
//为null就创建一个
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager = this.factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
RequestManager
RequestManager(
Glide glide,
//与页面生命周期绑定的lifecycle对象
Lifecycle lifecycle,
//提供基于当前上下文对RequestManager的relatives的访问。上下文层次结构是通过嵌套在Activity和Fragments中提供的;应用程序上下文不*提供对任何其他RequestManager的分层访问
RequestManagerTreeNode treeNode,
//请求追踪类
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
//会执行自身的onStart方法
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
//添加连接监视器
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
//添加注册监听
glide.registerRequestManager(this);
}
@Override
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
总结
- 初始化创建了Glide
- 创建engine、其他工厂
- 创建RequestManagerRetriever
- 绑定生命周期
- 创建对应的RequestManager
load
只看string类型,作为网络图片的url的。
asDrawable()
@Override
@NonNull
@CheckResult
public GlideRequest<Drawable> load(@Nullable String string) {
return (GlideRequest<Drawable>) super.load(string);
}
先看asDrawable()
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
这里是确定输出模型的,也可以说是不同的图片解码器。还记得如下代码:
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
创建一个新的请求构建器,用于加载Drawable类型。
//通用类,可以处理通用资源类型的设置选项和启动负载
protected RequestBuilder(
@NonNull Glide glide,
RequestManager requestManager,
Class<TranscodeType> transcodeClass,
Context context) {
this.glide = glide;
this.requestManager = requestManager;
this.transcodeClass = transcodeClass;
this.context = context;
//一些转换参数配置
this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
this.glideContext = glide.getGlideContext();
//初始化加载监听 onLoadFailed onResourceReady 两个回调
initRequestListeners(requestManager.getDefaultRequestListeners());
//执行 获取默认请求配置
apply(requestManager.getDefaultRequestOptions());
}
load
public RequestBuilder<TranscodeType> load(@Nullable Object model) {
return loadGeneric(model);
}
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
//这是个开关,into方法里面会用到
isModelSet = true;
return this;
}
into
首先
into
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
//禁止ui线程操作ui
Util.assertMainThread();
Preconditions.checkNotNull(view);
BaseRequestOptions<?> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
//类型转换
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.
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
再看into
方法:
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
//记得前面的load方法嘛,会把isModelSet设置为true
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
Request request = buildRequest(target, targetListener, options, callbackExecutor);
//target 上一次的Request
Request previous = target.getRequest();
//判断是否可以复用
//isSkipMemoryCacheWithCompletePreviousRequest 如果缓存操作没有完成,需要重写清理下
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
//如果请求完成,重新开始将确保结果重新传递,触发RequestListeners和Targets。如果请求失败,则重新开始将重新启动请求,从而给它另一个完成的机会。如果请求已经运行,我们可以让它继续运行而不会中断。
if (!Preconditions.checkNotNull(previous).isRunning()) {
//使用上一个请求而不是新请求来进行优化,例如跳过设置占位符,跟踪和取消跟踪目标,以及获取//在单个Request中完成的视图尺寸。
//使用上一个请求而不是新请求来进行优化
previous.begin();
}
return target;
}
//如果不能复用。先clear一下,再设置
requestManager.clear(target);
//进行与request的绑定,后面会通过vie.getTag()再拿到request
target.setRequest(request);
requestManager.track(target, request);
return target;
}
有一个代码需要解释下target.setRequest(request)
,这里会走到当前的view.setTag()
方法,大家应该会遇到Glide设置tag的冲突问题。
所以这里要看buildRequest
方法和begin
方法
buildRequest
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);
}
走buildRequestRecursive方法
private Request buildRequestRecursive(
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.
//如果手动设置error方法,并设置RequestBuilder,才会走下面
ErrorRequestCoordinator errorRequestCoordinator = null;
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
Request mainRequest =
buildThumbnailRequestRecursive(
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
if (errorRequestCoordinator == null) {
//默认情况下,是走这里的。
return mainRequest;
}
int errorOverrideWidth = errorBuilder.getOverrideWidth();
int errorOverrideHeight = errorBuilder.getOverrideHeight();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !errorBuilder.isValidOverride()) {
errorOverrideWidth = requestOptions.getOverrideWidth();
errorOverrideHeight = requestOptions.getOverrideHeight();
}
Request errorRequest =
errorBuilder.buildRequestRecursive(
target,
targetListener,
errorRequestCoordinator,
errorBuilder.transitionOptions,
errorBuilder.getPriority(),
errorOverrideWidth,
errorOverrideHeight,
errorBuilder,
callbackExecutor);
errorRequestCoordinator.setRequests(mainRequest, errorRequest);
return errorRequestCoordinator;
}
这里只看默认,所以不用管errorRequestCoordinator
之类的,其实就是多了一个错误情况下的处理。这里接着看Request创建流程,看buildThumbnailRequestRecursive
方法。
buildThumbnailRequestRecursive
private Request buildThumbnailRequestRecursive(
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
if (thumbnailBuilder != null) {
// Recursive case: contains a potentially recursive thumbnail request builder.
if (isThumbnailBuilt) {
throw new IllegalStateException("You cannot use a request as both the main request and a "
+ "thumbnail, consider using clone() on the request(s) passed to thumbnail()");
}
TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
thumbnailBuilder.transitionOptions;
// Apply our transition by default to thumbnail requests but avoid overriding custom options
// that may have been applied on the thumbnail request explicitly.
if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
thumbTransitionOptions = transitionOptions;
}
Priority thumbPriority = thumbnailBuilder.isPrioritySet()
? thumbnailBuilder.getPriority() : getThumbnailPriority(priority);
int thumbOverrideWidth = thumbnailBuilder.getOverrideWidth();
int thumbOverrideHeight = thumbnailBuilder.getOverrideHeight();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !thumbnailBuilder.isValidOverride()) {
thumbOverrideWidth = requestOptions.getOverrideWidth();
thumbOverrideHeight = requestOptions.getOverrideHeight();
}
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
Request fullRequest =
obtainRequest(
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
isThumbnailBuilt = true;
// Recursively generate thumbnail requests.
//递归操作 创建一个缩略图的请求Request
Request thumbRequest =
thumbnailBuilder.buildRequestRecursive(
target,
targetListener,
coordinator,
thumbTransitionOptions,
thumbPriority,
thumbOverrideWidth,
thumbOverrideHeight,
thumbnailBuilder,
callbackExecutor);
isThumbnailBuilt = false;
coordinator.setRequests(fullRequest, thumbRequest);
return coordinator;
} else if (thumbSizeMultiplier != null) {
// Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
//基本情况:缩略图生成器生成缩略图请求,不走递归。
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
Request fullRequest =
obtainRequest(
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
BaseRequestOptions<?> thumbnailOptions =
requestOptions.clone().sizeMultiplier(thumbSizeMultiplier);
Request thumbnailRequest =
obtainRequest(
target,
targetListener,
thumbnailOptions,
coordinator,
transitionOptions,
getThumbnailPriority(priority),
overrideWidth,
overrideHeight,
callbackExecutor);
coordinator.setRequests(fullRequest, thumbnailRequest);
return coordinator;
} else {
//默认情况下直接走这里的
// Base case: no thumbnail.
return obtainRequest(
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
}
有缩略图的设置才会走递归情况。默认情况是直接走obtainRequest
方法创建Request的。
obtainRequest
会再调用SingleRequest.obtain
,返回一个SingleRequest
的实例。
private static final Pools.Pool<SingleRequest<?>> POOL = FactoryPools.threadSafe(150,
new FactoryPools.Factory<SingleRequest<?>>() {
@Override
public SingleRequest<?> create() {
return new SingleRequest<Object>();
}
});
public static <R> SingleRequest<R> obtain(
Context context,
GlideContext glideContext,
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) {
//这是一个对象池模式
@SuppressWarnings("unchecked") SingleRequest<R> request =
(SingleRequest<R>) POOL.acquire();
if (request == null) {
//空的构造,还是要走init 初始化,更加符合对象池模式
request = new SingleRequest<>();
}
request.init(
context,
glideContext,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
engine,
animationFactory,
callbackExecutor);
return request;
}
对象池模式
这里从对象池获取SingleRequest并且初始化了。
begin
在拿到SingleRequest后回到into方法:requestManager.track(target, request);
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
//追踪用的
targetTracker.track(target);
requestTracker.runRequest(request);
}
//开始跟踪给定的请求。并且执行begin方法
public void runRequest(@NonNull Request request) {
//这个requests 保存了暂停 和 还没开始的请求
requests.add(request);
if (!isPaused) {
request.begin();
} else {
request.clear();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Paused, delaying request");
}
pendingRequests.add(request);
}
}
开始跟踪给定的请求。并且执行begin方法。
public synchronized void begin() {
assertNotCallingCallbacks();
stateVerifier.throwIfRecycled();
startTime = LogTime.getLogTime();
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;
}
//在初始化的时候 会设置为PENDING(已创建但尚未运行)
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));
}
}
target.getSize(this)
传入的是SizeReadyCallback
,而且SingleRequest实现了其方法,在大小确定后会回调onSizeReady
方法。
onSizeReady
public synchronized void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
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));
}
loadStatus =
engine.load(
glideContext,
model,
requestOptions.getSignature(),
this.width,
this.height,
requestOptions.getResourceClass(),
transcodeClass,
priority,
requestOptions.getDiskCacheStrategy(),
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.isScaleOnlyOrNoTransform(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getUseAnimationPool(),
requestOptions.getOnlyRetrieveFromCache(),
this,
callbackExecutor);
// This is a hack that's only useful for testing right now where loads complete synchronously
// even though under any executor running on any thread but the main thread, the load would
// have completed asynchronously.
if (status != Status.RUNNING) {
loadStatus = null;
}
if (IS_VERBOSE_LOGGABLE) {
logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
}
这里主要将一大堆参数传递给Engine
类的load
方法,Engine是在initializeGlide
里面初始化的。
load
//用来管理我们的EngineJob
private final Jobs jobs;
//负责创建缓存的key的工厂
private final EngineKeyFactory keyFactory;
private final MemoryCache cache;
private final EngineJobFactory engineJobFactory;
private final ResourceRecycler resourceRecycler;
private final LazyDiskCacheProvider diskCacheProvider;
//DecodeJob 对图片的原始资源进行解码转换
private final DecodeJobFactory decodeJobFactory;
private final ActiveResources activeResources;
public synchronized <R> LoadStatus load(
//Glide中所有加载的全局上下文,其中包含并公开了加载资源所需的各种注册表和类。
GlideContext glideContext,
//这个就是我们传过来的url
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);
//通过key,去当前存活的资源中找对应的图片,从弱引用中获取
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
//通过key去缓存里面拿 LruResourceCache 是一个lru缓存
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
//从文件缓存中去取
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);
}
//上面那些return null的都不用看
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);
//前面说的engineJob管理类
jobs.put(key, engineJob);
engineJob.addCallback(cb, callbackExecutor);
//如果前面那些缓存都没有。开始startjob
engineJob.start(decodeJob);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Started new load", startTime, key);
}
return new LoadStatus(cb, engineJob);
}
看EngineJob.start
方法:
//通过添加和删除负载的回调并在负载完成时通知回调来管理负载的类
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
//GlideExecutor 是一个线程池
//会区分到底是cache还是那存活的资源
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
//执行
executor.execute(decodeJob);
}
执行DecodeJob.run()
方法:
DecodeJob.run()
public void run() {
// This should be much more fine grained, but since Java's thread pool implementation silently
// swallows all otherwise fatal exceptions, this will at least make it obvious to developers
// that something is failing.
GlideTrace.beginSectionFormat("DecodeJob#run(model=%s)", model);
// Methods in the try statement can invalidate currentFetcher, so set a local variable here to
// ensure that the fetcher is cleaned up either way.
DataFetcher<?> localFetcher = currentFetcher;
try {
if (isCancelled) {
notifyFailed();
return;
}
runWrapped();
} catch (CallbackException e) {
// If a callback not controlled by Glide throws an exception, we should avoid the Glide
// specific debug logic below.
throw e;
} catch (Throwable t) {
// Catch Throwable and not Exception to handle OOMs. Throwables are swallowed by our
// usage of .submit() in GlideExecutor so we're not silently hiding crashes by doing this. We
// are however ensuring that our callbacks are always notified when a load fails. Without this
// notification, uncaught throwables never notify the corresponding callbacks, which can cause
// loads to silently hang forever, a case that's especially bad for users using Futures on
// background threads.
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "DecodeJob threw unexpectedly"
+ ", isCancelled: " + isCancelled
+ ", stage: " + stage, t);
}
// When we're encoding we've already notified our callback and it isn't safe to do so again.
if (stage != Stage.ENCODE) {
throwables.add(t);
notifyFailed();
}
if (!isCancelled) {
throw t;
}
throw t;
} finally {
// Keeping track of the fetcher here and calling cleanup is excessively paranoid, we call
// close in all cases anyway.
if (localFetcher != null) {
localFetcher.cleanup();
}
GlideTrace.endSection();
}
}
都是一些错误追踪代码和错误处理代码,只看 runWrapped()
方法就行。
runWrapped
//方法名 就是 执行包装类
private void runWrapped() {
switch (runReason) {
//第一次进来
case INITIALIZE:
//获取下次的状态
stage = getNextStage(Stage.INITIALIZE);
//获取下次的处理器,这里返回的是ResourceCacheGenerator
currentGenerator = getNextGenerator();
//再执行runGenerators
runGenerators();
break;
//重获取
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
//获取成功了
case DECODE_DATA:
decodeFromRetrievedData();
break;
default:
throw new IllegalStateException("Unrecognized run reason: " + runReason);
}
}
第一次进来runReason的值是INITIALIZE的,走该case,看getNextStage方法:
getNextStage & getNextGenerator
//这是一个递归方法
private Stage getNextStage(Stage current) {
switch (current) {
case INITIALIZE:
//第一次走这里
//decodeCachedResource 返回:如果此请求应尝试解码缓存的资源数据,则返回true。这里会返回true return Stage.RESOURCE_CACHE
return diskCacheStrategy.decodeCachedResource()
? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
case RESOURCE_CACHE:
//如果此请求应尝试解码缓存的源数据,则返回true。
return diskCacheStrategy.decodeCachedData()
? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
case DATA_CACHE:
// Skip loading from source if the user opted to only retrieve the resource from cache.
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);
}
}
runGenerators
这里会开启套娃模式,带着这个想法去看。
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
//循环条件会执行当前 currentGenerator的startNext方法
//1,而当前currentGenerator是INITIALIZE获取到的ResourceCacheGenerator,先由它调用startNext,它会返回false,执行循环代码
//1.1 获取下一个stage getNextStage()返回的是DATA_CACHE
//1.2 获取currentGenerator,getNextGenerator()方法下一个执行器 根据stage返回的是DataCacheGenerator
//1.3 判断stage == Stage.SOURCE fasle 继续循环
//2,当前currentGenerator 是上次循环赋值的为 DataCacheGenerator,判断条件还是走startNext,也是返回false,继续执行循环代码
//2.1 获取下一个stage getNextStage()返回的是SOURCE
//2.2 获取currentGenerator,getNextGenerator()方法下一个执行器 根据stage返回的是SourceGenerator,这个是我们真正需要的,我们第一加载是没有资源缓存和数据缓存的,所以上面ResourceCacheGenerator和DataCacheGenerator执行器除了做一些缓存判断,其实啥也没干,当然这是第一次加载没缓存确实没啥干的。
//2.3 判断stage == Stage.SOURCE true 执行reschedule() 跳出循环。
//3 执行reschedule() ,执行runReason = RunReason.SWITCH_TO_SOURCE_SERVICE,开启第二次大循环:
//3.1 callback.reschedule(this) 会走到EngineJob.reschedule方法
//3.2 execute(job) 又回到了run方法,又走到runWrapped()方法中
//3.3 此时的runReason 为SWITCH_TO_SOURCE_SERVICE,直接走runGenerators
//3.4 又回来了,判断while条件 ,此时经过前面1,2 步骤,stage为SOURCE,currentGenerator为SourceGenerator了,调用SourceGenerator的startNext方法了,这个会去获取资源
while (!isCancelled && currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
if (stage == Stage.SOURCE) {
reschedule();
return;
}
}
// We've run out of stages and generators, give up.
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
currentGenerator.startNext()是个非常重要的方法
步骤很麻烦,会走几次循环,最后才到了reschedule方法。也是为了读取用户的配置,都是有作用的,可以看下getNextStage的注解。
@Override
public void reschedule() {
runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
callback.reschedule(this);
}
会把runReason调整为SWITCH_TO_SOURCE_SERVICE状态,准备加载资源了。callback会回调到EngineJob.reschedule
方法。
@Override
public void reschedule(DecodeJob<?> job) {
// Even if the job is cancelled here, it still needs to be scheduled so that it can clean itself
// up.
getActiveSourceExecutor().execute(job);
}
线程又去执行DecodeJob.run方法,又回去了。所以又到了 runWrapped()方法了,但是runReason
的状态是SWITCH_TO_SOURCE_SERVICE
了,而且经过前面的处理stage
为SOURCE
,currentGenerator
为SourceGenerator
。所以再执行runGenerators方法,会调用SourceGenerator.startNext()
方法。
SourceGenerator.startNext()
public boolean startNext() {
//第一次没有缓存的
if (dataToCache != null) {
Object data = dataToCache;
dataToCache = null;
cacheData(data);
}
if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
return true;
}
sourceCacheGenerator = null;
loadData = null;
boolean started = false;
while (!started && hasNextModelLoader()) {
loadData = helper.getLoadData().get(loadDataListIndex++);
if (loadData != null
&& (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
|| helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
started = true;
//这里会拿到OkHttpStreamFetcher
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}
这里会获取到OkHttpStreamFetcher
去调用loadData方法,因为我们这传的是网络url,所以会走这个fetcher去加载。
loadData
public void loadData(@NonNull Priority priority,
@NonNull final DataCallback<? super InputStream> callback) {
//熟悉的okhttp3,创建一个 Request.Builder
Request.Builder requestBuilder = new Request.Builder().url(url.toStringUrl());
//添加头部,我们这边是字符串的url,所以不会走的
for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
String key = headerEntry.getKey();
requestBuilder.addHeader(key, headerEntry.getValue());
}
//创建Request
Request request = requestBuilder.build();
this.callback = callback;
//call请求数据
call = client.newCall(request);
call.enqueue(this);
}
再看这个类OkHttpStreamFetcher,是实现了okhttp3.Callback
接口的,所以是实现了onResponse
方法的,上面的异步网络请求成功后调用次方法。
onResponse
public void onResponse(@NonNull Call call, @NonNull Response response) {
responseBody = response.body();
if (response.isSuccessful()) {
long contentLength = Preconditions.checkNotNull(responseBody).contentLength();
stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);
//将请求成功的流数据回调给onDataReady方法了
callback.onDataReady(stream);
} else {
callback.onLoadFailed(new HttpException(response.message(), response.code()));
}
}
将请求成功的流数据回调给onDataReady方法了,所以看callback是谁传进来的,就找谁的实现。这里是由SourceGenerator传递进来的,而它又实现了DataCallback的接口,所以会重写onDataReady方法。
onDataReady
@Override
public void onDataReady(Object data) {
DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
//数据缓存赋值
dataToCache = data;
// We might be being called back on someone else's thread. Before doing anything, we should
// reschedule to get back onto Glide's thread.
//我们可能会在其他人的线程上被调用。在做任何事情之前,我们应该//重新计划以返回到Glide的线程。
cb.reschedule();
} else {
cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher,
loadData.fetcher.getDataSource(), originalKey);
}
}
调用reschedule方法,是不是很熟悉,又回到了DecodeJob.run()
方法。记住这里的dataToCache已经非空了,又回到了runWrapped
方法。在执行runGenerators
方法了:
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
//这里的状态 currentGenerator是 SourceGenerator
while (!isCancelled && currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
if (stage == Stage.SOURCE) {
reschedule();
return;
}
}
// We've run out of stages and generators, give up.
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
}
其实还是为了执行SourceGenerator.startNext
方法:
SourceGenerator.startNext
public boolean startNext() {
if (dataToCache != null) {
//再次进来,这里就不是空了,前面onDataReady执行的时候 有值了
Object data = dataToCache;
dataToCache = null;
cacheData(data);
}
//经过cacheData方法了,sourceCacheGenerator已经变成DataCacheGenerator了
if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
return true;
}
sourceCacheGenerator = null;
loadData = null;
boolean started = false;
while (!started && hasNextModelLoader()) {
loadData = helper.getLoadData().get(loadDataListIndex++);
if (loadData != null
&& (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
|| helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
started = true;
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}
private void cacheData(Object dataToCache) {
long startTime = LogTime.getLogTime();
try {
Encoder<Object> encoder = helper.getSourceEncoder(dataToCache);
DataCacheWriter<Object> writer =
new DataCacheWriter<>(encoder, dataToCache, helper.getOptions());
//helper 用于写入和读取磁盘缓存的工具类
originalKey = new DataCacheKey(loadData.sourceKey, helper.getSignature());
helper.getDiskCache().put(originalKey, writer);
} finally {
loadData.fetcher.cleanup();
}
//这里的sourceCacheGenerator 已经切换到了DataCacheGenerator了
sourceCacheGenerator =
new DataCacheGenerator(Collections.singletonList(loadData.sourceKey), helper, this);
}
经过变化sourceCacheGenerator变成DataCacheGenerator了,再执行DataCacheGenerator.startNext
方法了。
DataCacheGenerator.startNext
public boolean startNext() {
while (modelLoaders == null || !hasNextModelLoader()) {
sourceIdIndex++;
if (sourceIdIndex >= cacheKeys.size()) {
//第一次走的这里
return false;
}
Key sourceId = cacheKeys.get(sourceIdIndex);
//创建缓存的key
Key originalKey = new DataCacheKey(sourceId, helper.getSignature());
//保存起来
cacheFile = helper.getDiskCache().get(originalKey);
if (cacheFile != null) {
this.sourceKey = sourceId;
modelLoaders = helper.getModelLoaders(cacheFile);
modelLoaderIndex = 0;
}
}
loadData = null;
boolean started = false;
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;
//这里是字节流的Fetcher ByteBufferFileLoader
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}
ByteBufferFileLoader.load
方法会回调到DataCacheGenerator.onDataReady
方法,再到SourceGenerator.onDataFetcherReady
方法,再到DecodeJob.onDataFetcherReady
。
decodeFromRetrievedData
private void decodeFromRetrievedData() {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Retrieved data", startFetchTime,
"data: " + currentData
+ ", cache key: " + currentSourceKey
+ ", fetcher: " + currentFetcher);
}
Resource<R> resource = null;
try {
//decodeFromData 就不看了,一些列的解码流程,获取到资源,最终会把流转为drawable、bitmap等。
resource = decodeFromData(currentFetcher, currentData, currentDataSource);
} catch (GlideException e) {
e.setLoggingDetails(currentAttemptingKey, currentDataSource);
throwables.add(e);
}
if (resource != null) {
//解码完成的回调与释放
notifyEncodeAndRelease(resource, currentDataSource);
} else {
runGenerators();
}
}
notifyEncodeAndRelease
private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
if (resource instanceof Initializable) {
((Initializable) resource).initialize();
}
Resource<R> result = resource;
LockedResource<R> lockedResource = null;
if (deferredEncodeManager.hasResourceToEncode()) {
lockedResource = LockedResource.obtain(resource);
result = lockedResource;
}
//通知原线程开始处理图片,就是主线程
notifyComplete(result, dataSource);
//更换状态
stage = Stage.ENCODE;
try {
//判断是否可以转换为 磁盘缓存
if (deferredEncodeManager.hasResourceToEncode()) {
deferredEncodeManager.encode(diskCacheProvider, options);
}
} finally {
if (lockedResource != null) {
lockedResource.unlock();
}
}
// Call onEncodeComplete outside the finally block so that it's not called if the encode process
// throws.
onEncodeComplete();
}
看下notifyComplete
方法
private void notifyComplete(Resource<R> resource, DataSource dataSource) {
setNotifiedOrThrow();
//这个callback就是DecodeJob初始化传进来的,就是EngineJob实现了DecodeJob.Callback
callback.onResourceReady(resource, dataSource);
}
EngineJob.onResourceReady
@Override
public void onResourceReady(Resource<R> resource, DataSource dataSource) {
synchronized (this) {
this.resource = resource;
this.dataSource = dataSource;
}
notifyCallbacksOfResult();
}
EngineJob.notifyCallbacksOfResult
void notifyCallbacksOfResult() {
ResourceCallbacksAndExecutors copy;
Key localKey;
EngineResource<?> localResource;
synchronized (this) {
stateVerifier.throwIfRecycled();
if (isCancelled) {
//取消操作,这次不会执行
resource.recycle();
release();
return;
} else if (cbs.isEmpty()) {
throw new IllegalStateException("Received a resource without any callbacks to notify");
} else if (hasResource) {
throw new IllegalStateException("Already have resource");
}
engineResource = engineResourceFactory.build(resource, isCacheable);
// Hold on to resource for duration of our callbacks below so we don't recycle it in the
// middle of notifying if it synchronously released by one of the callbacks. Acquire it under
// a lock here so that any newly added callback that executes before the next locked section
// below can't recycle the resource before we call the callbacks.
hasResource = true;
copy = cbs.copy();
incrementPendingCallbacks(copy.size() + 1);
localKey = key;
localResource = engineResource;
}
//这里就是把资源放到弱引用的缓存里面
listener.onEngineJobComplete(this, localKey, localResource);
for (final ResourceCallbackAndExecutor entry : copy) {
//遍历每一个回调接口,entry.cb 就是SingleRequest 对象,执行接口ResourceCallback
entry.executor.execute(new CallResourceReady(entry.cb));
}
decrementPendingCallbacks();
}
CallResourceReady
private class CallResourceReady implements Runnable {
private final ResourceCallback cb;
CallResourceReady(ResourceCallback cb) {
this.cb = cb;
}
@Override
public void run() {
synchronized (EngineJob.this) {
if (cbs.contains(cb)) {
// Acquire for this particular callback.
//资源回收
engineResource.acquire();
//执行资源回调
callCallbackOnResourceReady(cb);
removeCallback(cb);
}
decrementPendingCallbacks();
}
}
}
synchronized void callCallbackOnResourceReady(ResourceCallback cb) {
try {
// This is overly broad, some Glide code is actually called here, but it's much
// simpler to encapsulate here than to do so at the actual call point in the
// Request implementation.
cb.onResourceReady(engineResource, dataSource);
} catch (Throwable t) {
throw new CallbackException(t);
}
}
这里的cb又回到了SingleRequest
了:
SingleRequest.onResourceReady
public synchronized void onResourceReady(Resource<?> resource, DataSource dataSource) {
stateVerifier.throwIfRecycled();
loadStatus = null;
if (resource == null) {
GlideException exception = new GlideException("Expected to receive a Resource<R> with an "
+ "object of " + transcodeClass + " inside, but instead got null.");
onLoadFailed(exception);
return;
}
Object received = resource.get();
if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
releaseResource(resource);
GlideException exception = new GlideException("Expected to receive an object of "
+ transcodeClass + " but instead" + " got "
+ (received != null ? received.getClass() : "") + "{" + received + "} inside" + " "
+ "Resource{" + resource + "}."
+ (received != null ? "" : " " + "To indicate failure return a null Resource "
+ "object, rather than a Resource object containing null data."));
onLoadFailed(exception);
return;
}
if (!canSetResource()) {
releaseResource(resource);
// We can't put the status to complete before asking canSetResource().
status = Status.COMPLETE;
return;
}
//重载了
onResourceReady((Resource<R>) resource, (R) received, dataSource);
}
private synchronized void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
// We must call isFirstReadyResource before setting status.
boolean isFirstResource = isFirstReadyResource();
status = Status.COMPLETE;
this.resource = resource;
if (glideContext.getLogLevel() <= Log.DEBUG) {
Log.d(GLIDE_TAG, "Finished loading " + result.getClass().getSimpleName() + " from "
+ dataSource + " for " + model + " with size [" + width + "x" + height + "] in "
+ LogTime.getElapsedMillis(startTime) + " ms");
}
isCallingCallbacks = true;
try {
boolean anyListenerHandledUpdatingTarget = false;
if (requestListeners != null) {
for (RequestListener<R> listener : requestListeners) {
anyListenerHandledUpdatingTarget |=
listener.onResourceReady(result, model, target, dataSource, isFirstResource);
}
}
anyListenerHandledUpdatingTarget |=
targetListener != null
&& targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);
if (!anyListenerHandledUpdatingTarget) {
Transition<? super R> animation =
animationFactory.build(dataSource, isFirstResource);
//会执行到这里,最后的加载位置
target.onResourceReady(result, animation);
}
} finally {
isCallingCallbacks = false;
}
notifyLoadSuccess();
}
而这里的target就是DrawableImageViewTarget,也就是包含view自身的view
DrawableImageViewTarget.setResource
public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
public DrawableImageViewTarget(ImageView view) {
super(view);
}
/**
* @deprecated Use {@link #waitForLayout()} instead.
*/
// Public API.
@SuppressWarnings({"unused", "deprecation"})
@Deprecated
public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
super(view, waitForLayout);
}
@Override
protected void setResource(@Nullable Drawable resource) {
//加载资源,熟悉的方法
view.setImageDrawable(resource);
}
}
总结
这个流程是真的很长很长,也很绕。
网上找的几张图,过度时间自己画一张。
大概就是 :先找活动资源(这个就是那个弱引用)、找不到再找内存缓存(loadFromMemory方法和LruCache)、找不到就从磁盘缓存去取(根据DiskCacheStrategy不同有所不同。但资源分为:转换后资源 和 原始资源),还是找不到就只有网络请求或者资源读取,再拿到资源后,又根据配置(DiskCacheStrategy)去存起来,把资源当作存回去了。