前言
开始
基本使用非常简单,链式调用把context对象传入,设置要加载的URL,设置要填充的ImageView控件,方法很简洁,每次都是传入的最核心的参数,底层加载的缓存逻辑,加载的引擎,加载的对象的适配,URL的适配…都为我们做了封装。使用者无需关心这些细节就可以实现图片的加载。这才是优秀的库该有的样子足够简洁,但是足够强大。把复杂留给自己,把简单留给用户。
Glide.with(fragment)
.load(myUrl)
.into(imageView);
With方法
前面看了Glide的基本使用,Glide是外观类,我们先看前面例子中的with方法
with相关的重载方法有四个,最终都是返回一个RequestManager,后面调用load方法用的就是返回的RequestManager。
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getContext()).get(fragment);
}
@NonNull
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
都是先调用getRetriever(),getRetriever()方法是Glide的静态方法,会返回一个RequestManagerRetriever。这个方法中会引出Glide的构造,最终通过调用Glide实例的getRequestManagerRetriever方法返回RequestManagerRetriever。
@NonNull
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, DESTROYED_ACTIVITY_WARNING);
return Glide.get(context).getRequestManagerRetriever();
}
//双重校验锁单例模式获取Glide,glide实例是被volatile修饰
@NonNull
// Double checked locking is safe here.
@SuppressWarnings("GuardedBy")
public static Glide get(@NonNull Context context) {
if (glide == null) {
//这里通过反射创建一个GeneratedAppGlideModuleImpl的实例
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
//检查是否初始化过Glide
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
继续看checkAndInitializeGlide方法,检查并初始化Glide
static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
// In the thread running initGlide(), one or more classes may call Glide.get(context).
//初始化中,其他类也可能调用Glide.get
// Without this check, those calls could trigger infinite recursion.
//如果没有这个校验,有可能触发无线递归
if (isInitializing) {
throw new IllegalStateException(
"Glide has been called recursively, this is probably an internal library error!");
}
//标记正在初始化中
isInitializing = true;
try {
initializeGlide(context, generatedAppGlideModule);
} finally {
//标记初始化中为false
isInitializing = false;
}
}
@GuardedBy("Glide.class")
private static void initializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
//新建一个GlideBuilder传入
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
//获取getApplicationContext,这里我们要知道构造Glide是全局唯一的
Context applicationContext = context.getApplicationContext();
List<GlideModule> manifestModules = Collections.emptyList();
//GlideModule相关处理,先忽略
...
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory()
: null;
builder.setRequestManagerFactory(factory);
for (GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
//构造Glide
Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
//注册ComponentCallback
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
这里注意在initializeGlide方法中用的是applicationContext,不依赖某个Activity,Service,Fragment等。为什么提一下这个,因为后面RequestManager的生成不是这样的,后面做下区分。
@NonNull
Glide build(
@NonNull Context context,
List<GlideModule> manifestModules,
AppGlideModule annotationGeneratedGlideModule) {
//设置资源执行器
if (sourceExecutor == null) {
sourceExecutor = GlideExecutor.newSourceExecutor();
}
//设置磁盘缓存执行器
if (diskCacheExecutor == null) {
diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
}
//设置动画执行器
if (animationExecutor == null) {
animationExecutor = GlideExecutor.newAnimationExecutor();
}
//设置内存计算器
if (memorySizeCalculator == null) {
memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
}
//设置连接监控工厂
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
//构造Bitmap复用池
if (bitmapPool == null) {
int size = memorySizeCalculator.getBitmapPoolSize();
if (size > 0) {
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}
if (arrayPool == null) {
arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
}
//构造内存缓存
if (memoryCache == null) {
memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
}
//构造磁盘缓存工厂
if (diskCacheFactory == null) {
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
//创建引擎
if (engine == null) {
engine =
new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
if (defaultRequestListeners == null) {
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}
GlideExperiments experiments = glideExperimentsBuilder.build();
//新建一个RequestManagerRetriever
//这里注意后面load方法会用到这个requestManagerRetriever来获取RequestManager
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);
//构造Glide,传入以上实例作为参数
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
manifestModules,
annotationGeneratedGlideModule,
experiments);
}
构造方法
Glide(
@NonNull Context context,
@NonNull Engine engine,
@NonNull MemoryCache memoryCache,
@NonNull BitmapPool bitmapPool,
@NonNull ArrayPool arrayPool,
@NonNull RequestManagerRetriever requestManagerRetriever,
@NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
int logLevel,
@NonNull RequestOptionsFactory defaultRequestOptionsFactory,
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
@NonNull List<RequestListener<Object>> defaultRequestListeners,
@NonNull List<GlideModule> manifestModules,
@Nullable AppGlideModule annotationGeneratedModule,
@NonNull GlideExperiments experiments) {
this.engine = engine;
this.bitmapPool = bitmapPool;
this.arrayPool = arrayPool;
this.memoryCache = memoryCache;
this.requestManagerRetriever = requestManagerRetriever;
this.connectivityMonitorFactory = connectivityMonitorFactory;
this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
// This has a circular relationship with Glide and GlideContext in that it depends on both,
// but it's created by Glide's constructor. In practice this shouldn't matter because the
// supplier holding the registry should never be initialized before this constructor finishes.
GlideSupplier<Registry> registry =
RegistryFactory.lazilyCreateAndInitializeRegistry(
this, manifestModules, annotationGeneratedModule);
ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
//新建一个GlideContext,并传递大部分构造方法的参数进去
glideContext =
new GlideContext(
context,
arrayPool,
registry,
imageViewTargetFactory,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
engine,
experiments,
logLevel);
}
现在getRetriever()方法基本看完,核心就是为我们构造出了Glide单例,然后调用Glide的getRequestManagerRetriever()得到RequestManagerRetriever
@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
这个requestManagerRetriever在Glide构造方法的时候看到过,构造的时候,新建并传递了requestManagerRetriever参数。现在让我们回退再回到with方法,先通过getRetriever方法得到一个RequestManagerRetriever,然后调用它的get方法。下面去看RequestManagerRetriever的get方法,get方法主要是获取一个RequestManager。基本上跟Glide的with方法一一对应,不一样的是with方法最终都调用到了一个方法,而这个get实现都有些区别。
@NonNull
public RequestManager get(@NonNull Context context) {...}
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {...}
@NonNull
public RequestManager get(@NonNull Fragment fragment) {...}
@NonNull
public RequestManager get(@NonNull View view) {...}
上面这四种,第四种其实是分情况如果找到这个View的Activity,Activity是否是属于FragmentActivity,是FragmentActivity的话是否是属于Fragment等最终是调用前三种的一个,所以主要分为三种类型:
- 参数为FragmentActivity
- 参数为Fragment
- 参数为Context
参数为FragmentActivity
public RequestManager get(@NonNull FragmentActivity activity) {
...
//是否可见
boolean isActivityVisible = isActivityVisible(activity);
//获取Glide单例
Glide glide = Glide.get(activity.getApplicationContext());
//调用lifecycleRequestManagerRetriever的getOrCreate
return lifecycleRequestManagerRetriever.getOrCreate(
activity,
glide,
activity.getLifecycle(),
activity.getSupportFragmentManager(),
isActivityVisible);
}
lifecycleRequestManagerRetriever是在RequestManagerRetriever构造方法中新建的,也就意味着Glide单例新建之前已经构造好了lifecycleRequestManagerRetriever实例。
注意第三个参数是getLifecycle,只有ComponentActivity才有这个方法,Activity中是没有这个方法的,这也就是为什么这个参数传入的不是Activity的原因。通过这个Lifecycle可以监控activity的生命周期。也就能及时回收,避免发生内存泄露。
接着看getOrCreate
RequestManager getOrCreate(
Context context,
Glide glide,
final Lifecycle lifecycle,
FragmentManager childFragmentManager,
boolean isParentVisible) {
//断言在主线程,不在的话抛异常
Util.assertMainThread();
//看名字大概是根据lifecycle为key,获取唯一的RequestManager
RequestManager result = getOnly(lifecycle);
if (result == null) {
//LifecycleLifecycle这名字起的。。其实是它实现了glide自己的Lifecycle
//同时又实现了Android的LifecycleObserver
LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
//构造一个新的
result =
factory.build(
glide,
glideLifecycle,
new SupportRequestManagerTreeNode(childFragmentManager),
context);
//存放到lifecycleToRequestManager这个Map中
lifecycleToRequestManager.put(lifecycle, result);
glideLifecycle.addListener(
new LifecycleListener() {
@Override
public void onStart() {}
@Override
public void onStop() {}
@Override
public void onDestroy() {
lifecycleToRequestManager.remove(lifecycle);
}
});
// This is a bit of hack, we're going to start the RequestManager, but not the
// corresponding Lifecycle. It's safe to start the RequestManager, but starting the
// Lifecycle might trigger memory leaks. See b/154405040
if (isParentVisible) {
//如果Parent可见,直接执行onStart()方法
result.onStart();
}
}
//返回RequestManager
return result;
}
接着看RequestManager的构建,这里使用的是工厂模式,factory是LifecycleRequestManagerRetriever构造的时候传入的,LifecycleRequestManagerRetriever的构造是在RequestManagerRetriever的构造方法中,也就是Glide构造之前。RequestManagerRetriever的构造方法中传入了factory,为空的话会使用DEFAULT_FACTORY,什么时候不为空呢,就是在initializeGlide方法中annotationGeneratedModule.getRequestManagerFactory()不为空,这里先不深入,我们直接看DEFAULT_FACTORY。
private static final RequestManagerFactory DEFAULT_FACTORY =
new RequestManagerFactory() {
@NonNull
@Override
public RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context) {
直接new了一个RequestManager
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
最终调用到
RequestManager(
Glide glide,
Lifecycle lifecycle,
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));
// Order matters, this might be unregistered by teh listeners below, so we need to be sure to
// register first to prevent both assertions and memory leaks.
glide.registerRequestManager(this);
// If we're the application level request manager, we may be created on a background thread.
// In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
// issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
// This should be entirely safe.
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
}
参数为Fragment
基本同参数为FragmentActivity,不同的是lifecycle这里获取的是fragment.getLifecycle(),感兴趣的可以自行查阅源码
参数为Context
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof ContextWrapper
// Only unwrap a ContextWrapper if the baseContext has a non-null application context.
// Context#createPackageContext may return a Context without an Application instance,
// in which case a ContextWrapper may be used to attach one.
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
到这里我们了解了RequestManager的生成过程。
总结:With阶段主要为:
- 获取RequestManagerRetriever,获取过程中若未构建Glide,帮我们构建好Glide单例
- 有了RequestManagerRetriever,通过RequestManagerRetriever的get方法获取RequestManager,不同的context(Activity,Fragment,ApplicationContext)得到不同的RequestManager
至此,with方法分析完成,为我们完成加载图片前的平台侧准备工作,这里的平台指的是Glide。
load方法解析
前面讲解构造函数知道load(url)是RequestManager的方法,RequestManager是用来管理和启动request的。
A class for managing and starting requests for Glide.
RequestManager是with方法中getRetriever(context).get(context)获取的。getRetriever(context)得到RequestManagerRetriever,然后调用RequestManagerRetriever的get方法获取RequestManager。
现在去看下load方法,这里我们就比较熟悉了,我们知道glide非常贴心的为我们支持了很多类型,Bitmap,url,drawable, 资源id,文件等等。
//RequestManager.java
public RequestBuilder<Drawable> load(@Nullable Bitmap bitmap) {
return asDrawable().load(bitmap);
}
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
public RequestBuilder<Drawable> load(@Nullable Uri uri) {
return asDrawable().load(uri);
}
public RequestBuilder<Drawable> load(@Nullable File file) {
return asDrawable().load(file);
}
public RequestBuilder<Drawable> load(@RawRes @DrawableRes @Nullable Integer resourceId) {
return asDrawable().load(resourceId);
}
public RequestBuilder<Drawable> load(@Nullable URL url) {
return asDrawable().load(url);
}
public RequestBuilder<Drawable> load(@Nullable byte[] model) {
return asDrawable().load(model);
}
public RequestBuilder<Drawable> load(@Nullable Object model) {
return asDrawable().load(model);
}
他们都调用了一个asDrawable()方法,返回一个RequestBuilder,是一个泛型类,可以处理泛型资源类型的设置选项和开始加载。既然是泛型类,除了这里的Drawable,还用到哪些类型呢?还有Bitmap,GifDrawable,File,这里主要分析核心流程,这里主要看Drawable,也是我们最常用的。下面去看下asDrawable的实现。
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
//构造RequestBuilder,注意这几个参数,第一个参数是glide对象,第二个是RequestManager自身,
//第三个是resourceClass,也即是传进来的Drawable.class对象,第四个是上下文
return new RequestBuilder<>(glide, this, resourceClass, context);
}
asDrawable()也是返回一个RequestBuilder,前面RequestManager的load方法中都是调用了asDrawable().load方法,也就是RequestBuilder的load方法,说明后面执行load方法的也是新建的这个RequestBuilder执行的。然后再来看下
//RequestBuilder.java
public RequestBuilder<TranscodeType> load(@Nullable String string) {
//把参数传过去
return loadGeneric(string);
}
@NonNull
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
if (isAutoCloneEnabled()) {
return clone().loadGeneric(model);
}
//这里model是一个Object,也就是可以接受任意类型
this.model = model;
isModelSet = true;
return selfOrThrowIfLocked();
}
其实就是给this.mode赋值,然后设置isModelSet为true,然后返回自身,也就是刚刚新建的RequestBuilder,RequestBuilder是BaseRequestOptions的子类。
//BaseRequestOptions.java
protected final T selfOrThrowIfLocked() {
if (isLocked) {
throw new IllegalStateException("You cannot modify locked T, consider clone()");
}
return self();
}
private T self() {
return (T) this;
}
总结:load方法看着比较简单,仅仅是构造了一个RequestBuilder,后面调用的into方法也在RequestBuilder中,所以可以认为这里仅仅是对请求参数的一个准备,适配了所有的类型Bitmap,url,drawable, 资源id,文件等等。
into方法分析
前面主要是拿到了RequestBuilder对象,执行into方法的是在RequestBuilder中
//RequestBuilder.java
@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
//检查是否在主线程,否则抛异常
Util.assertMainThread();
//检查要显示图片的view是否为空
Preconditions.checkNotNull(view);
//赋值BaseRequestOptions,RequestBuilder继承自BaseRequestOptions
BaseRequestOptions<?> requestOptions = this;
//判断是否设置Transformation等变换
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
// Clone in this method so that if we use this RequestBuilder to load into a View and then
// into a different target, we don't retain the transformation applied based on the previous
// View's scale type.
switch (view.getScaleType()) {
case CENTER_CROP:
//这里用到了原型模式
requestOptions = requestOptions.clone().optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
requestOptions = requestOptions.clone().optionalFitCenter();
break;
case FIT_XY:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case CENTER:
case MATRIX:
default:
// Do nothing.
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/* targetListener= */ null,
requestOptions,
Executors.mainThreadExecutor());
}
看下传入的几个参数
- glideContext.buildImageViewTarget(view, transcodeClass) -> 构建一个Target对象
- null->targetListener传入的为空
- requestOptions->也就是自身
- Executor->这里传入的是主线程Executor
这里我们先看下Target的构造过程,后面会用到
//GlideContext.java
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
//将ImageView和transcodeClass调用imageViewTargetFactory的buildTarget
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
ImageViewTargetFactory的buildTarget方法是根据transcodeClass类型创建不同的Target,如BitmapImageViewTarget和DrawableImageViewTarget
//ImageViewTargetFactory.java
public <Z> ViewTarget<ImageView, Z> buildTarget(
@NonNull ImageView view, @NonNull Class<Z> clazz) {
if (Bitmap.class.equals(clazz)) {
return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
} 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)");
}
}
//RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
//检查target是否为null
Preconditions.checkNotNull(target);
//还记得前面load方法中有设置这个为true
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
//构建request
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest();
//拿到上一次的request,如果和以前的一样
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
//如果request已经完成,重新开始以保证结果可以被传递
//如果request已经失败,重新开始请求,给它第二次成功的机会
//如果在运行,我们让他继续运行
if (!Preconditions.checkNotNull(previous).isRunning()) {
// Use the previous request rather than the new one to allow for optimizations like skipping
// setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
// that are done in the individual Request.
previous.begin();
}
return target;
}
//清空target
requestManager.clear(target);
//给target设置为当前的request
target.setRequest(request);
//添加追踪,并开始执行
requestManager.track(target, request);
return target;
}
后面分三个方向,这三个方法也是into方法主要做的几件事:
- 如何构造request
- 如何请求request
- 如何把请求结果显示到ImageView上
如何构造request
private Request buildRequest(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(
/* requestLock= */ new Object(),//请求锁
target,//目标
targetListener,//目标监听器,前面看到这里传来的是null
/* parentCoordinator= */ null,
transitionOptions,//转换选项
requestOptions.getPriority(),//请求选项-优先级
requestOptions.getOverrideWidth(),//请求选项-复写宽度
requestOptions.getOverrideHeight(),//请求选项-复写高度
requestOptions,//请求选项
callbackExecutor //回调执行器
);
}
private Request buildRequestRecursive(...) {
// Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
ErrorRequestCoordinator errorRequestCoordinator = null;
//前面Demo没有设置error,这里为null
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
Request mainRequest =
buildThumbnailRequestRecursive(
requestLock,
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
if (errorRequestCoordinator == null) {
return mainRequest;
}
...
return errorRequestCoordinator;
}
private Request buildThumbnailRequestRecursive(
Object requestLock,
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
if (thumbnailBuilder != null) {
//前面Demo中没有设置thumbnail,不会走到这里先忽略
...
} else if (thumbSizeMultiplier != null) {
//前面Demo中没有设置thumbnail,不会走到这里先忽略
...
} else {
// Base case: no thumbnail.
return obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
}
最后走到obtainRequest,通过SingleRequest.obtain,最终在SingleRequest.java中直接新建了一个SingleRequest
private Request obtainRequest(
Object requestLock,
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
RequestCoordinator requestCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
Executor callbackExecutor) {
return SingleRequest.obtain(
context,
glideContext,
requestLock,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
glideContext.getEngine(),
transitionOptions.getTransitionFactory(),
callbackExecutor);
}
如何请求request
通过看Request接口说明,知道begin()是开始一个请求,在前面requestManager.track(target, request);会最终调用到begin()方法。
//RequestManager.java
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
//RequestTracker.java
public void runRequest(@NonNull Request request) {
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);
}
}
public interface Request {
//启动一个异步请求
void begin();
//取消,清空请求
void clear();
//暂停请求
void pause();
//是否在运行中
boolean isRunning();
//请求是否完成
boolean isComplete();
//请求是否被clear
boolean isCleared();
/**
* Returns true if a resource is set, even if the request is not yet complete or the primary
* request has failed.
*/
boolean isAnyResourceSet();
//和另一个请求是否相等
boolean isEquivalentTo(Request other);
}
下面我们去看SingleRequest的begin方法的实现
//SingleRequest.java
public void begin() {
synchronized (requestLock) {
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;
}
if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}
// If we're restarted after we're complete (usually via something like a notifyDataSetChanged
// that starts an identical request into the same Target or View), we can simply use the
// resource and size we retrieved the last time around and skip obtaining a new size, starting
// a new load etc. This does mean that users who want to restart a load because they expect
// that the view size has changed will need to explicitly clear the View or Target before
// starting the new load.
if (status == Status.COMPLETE) {
onResourceReady(
resource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
return;
}
// Restarts for requests that are neither complete nor running can be treated as new requests
// and can run again from the beginning.
experimentalNotifyRequestStarted(model);
cookie = GlideTrace.beginSectionAsync(TAG);
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
//如果overrideWidth,overrideHeight都是有效的,直接调用onSizeReady
onSizeReady(overrideWidth, overrideHeight);
} else {
//否则调用target.getSize,并把自身传入,因为SingleRequest实现了SizeReadyCallback,获取成功最终还是回调到onSizeReady方法
target.getSize(this);
}
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
if (IS_VERBOSE_LOGGABLE) {
logV("finished run method in " + LogTime.getElapsedMillis(startTime));
}
}
}
最终都是调用到onSizeReady方法,onSizeReady方法中调用的是engine的load方法,engine是在Glide的建造者中构造的
//SingleRequest.java
public void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
synchronized (requestLock) {
if (IS_VERBOSE_LOGGABLE) {
logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
if (status != Status.WAITING_FOR_SIZE) {
//如果还在等待size结果。直接返回
return;
}
//将status设置为Status.RUNNING
status = Status.RUNNING;
float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
if (IS_VERBOSE_LOGGABLE) {
logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
}
//调用引擎的load方法加载图片
loadStatus =
engine.load(
glideContext,
model,
requestOptions.getSignature(),
this.width,
this.height,
requestOptions.getResourceClass(),
transcodeClass,
priority,
requestOptions.getDiskCacheStrategy(),
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.isScaleOnlyOrNoTransform(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getUseAnimationPool(),
requestOptions.getOnlyRetrieveFromCache(),
this,//传入回调
callbackExecutor);
// 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));
}
}
}
需要注意的是load方法传入了一个ResourceCallback cb参数,这个接口就是加载结果的回调。
public interface ResourceCallback {
//加载成功
void onResourceReady(
Resource<?> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey);
//加载失败
void onLoadFailed(GlideException e);
Object getLock();
}
//Engine.java
public <R> LoadStatus load(...) {
long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;
EngineKey key =
keyFactory.buildKey(
model,
signature,
width,
height,
transformations,
resourceClass,
transcodeClass,
options);
EngineResource<?> memoryResource;
//加锁,同一时间内只能添加一个加载工作
synchronized (this) {
//先重缓存中加载
memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
if (memoryResource == null) {
//缓存没有
return waitForExistingOrStartNewJob(
glideContext,
model,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
options,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache,
cb,
callbackExecutor,
key,
startTime);
}
}
// Avoid calling back while holding the engine lock, doing so makes it easier for callers to
// deadlock.
cb.onResourceReady(
memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
return null;
}
分析缓存加载流程
//Engine.java
private EngineResource<?> loadFromMemory(
EngineKey key, boolean isMemoryCacheable, long startTime) {
if (!isMemoryCacheable) {
return null;
}
//先从活跃缓存中加载
EngineResource<?> active = loadFromActiveResources(key);
if (active != null) {
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return active;
}
//活跃缓存没有找到,继续去非活跃缓存中加载
EngineResource<?> cached = loadFromCache(key);
if (cached != null) {
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return cached;
}
//都没查到,返回null
return null;
}
活跃缓存是直接在Map中
private EngineResource<?> loadFromActiveResources(Key key) {
//ActiveResources的实例,里面存放的是Map<Key, ResourceWeakReference>
EngineResource<?> active = activeResources.get(key);
if (active != null) {
active.acquire();
}
return active;
}
从缓存中加载,缓存对象是Engine构造的时候传入的,最开始在Glide构建时候新建的LruResourceCache,是Glide自己实现的LRU
private EngineResource<?> loadFromCache(Key key) {
EngineResource<?> cached = getEngineResourceFromCache(key);
if (cached != null) {
cached.acquire();
activeResources.activate(key, cached);
}
return cached;
}
private EngineResource<?> getEngineResourceFromCache(Key key) {
Resource<?> cached = cache.remove(key);
final EngineResource<?> result;
if (cached == null) {
result = null;
} else if (cached instanceof EngineResource) {
// Save an object allocation if we've cached an EngineResource (the typical case).
result = (EngineResource<?>) cached;
} else {
result =
new EngineResource<>(
cached,
/* isMemoryCacheable= */ true,
/* isRecyclable= */ true,
key,
/* listener= */ this);
}
return result;
}
缓存没有查到,会调用waitForExistingOrStartNewJob方法,等待已经存在的任务或者开启新的任务。
//Engine.java
private <R> LoadStatus waitForExistingOrStartNewJob(...) {
//先从jobs里面查询是否有加入过
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb, callbackExecutor);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
//查询到,直接返回LoadStatus,加载的状态
return new LoadStatus(cb, current);
}
//没查到,通过engineJobFactory工厂构建一个新的EngineJob
EngineJob<R> engineJob =
engineJobFactory.build(
key,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache);
//在通过解码job工厂构建一个新的解码job
DecodeJob<R> decodeJob =
decodeJobFactory.build(
glideContext,
model,
key,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
onlyRetrieveFromCache,
options,
engineJob);
//添加到 jobs里面
jobs.put(key, engineJob);
//添加回调
engineJob.addCallback(cb, callbackExecutor);
//启动加载工作
engineJob.start(decodeJob);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Started new load", startTime, key);
}
//返回加载状态
return new LoadStatus(cb, engineJob);
}
下面分析几个点
- Jobs
- LoadStatus
- EngineJob
- DecodeJob
Jobs
Jobs比较简单,可以理解为就是个工作存储器。有两个Map,
- jobs 存储普通服务的Map
- onlyCacheJobs 存储只从缓存取的job的Map
final class Jobs {
private final Map<Key, EngineJob<?>> jobs = new HashMap<>();
private final Map<Key, EngineJob<?>> onlyCacheJobs = new HashMap<>();
@VisibleForTesting
Map<Key, EngineJob<?>> getAll() {
return Collections.unmodifiableMap(jobs);
}
EngineJob<?> get(Key key, boolean onlyRetrieveFromCache) {
return getJobMap(onlyRetrieveFromCache).get(key);
}
void put(Key key, EngineJob<?> job) {
getJobMap(job.onlyRetrieveFromCache()).put(key, job);
}
void removeIfCurrent(Key key, EngineJob<?> expected) {
Map<Key, EngineJob<?>> jobMap = getJobMap(expected.onlyRetrieveFromCache());
if (expected.equals(jobMap.get(key))) {
jobMap.remove(key);
}
}
private Map<Key, EngineJob<?>> getJobMap(boolean onlyRetrieveFromCache) {
return onlyRetrieveFromCache ? onlyCacheJobs : jobs;
}
}
LoadStatus
LoadStatus就更简单了,仅仅是包装了engineJob和cb()回调。并提供了一个cancel方法。所以核心就是可以取消请求。
public class LoadStatus {
private final EngineJob<?> engineJob;
private final ResourceCallback cb;
LoadStatus(ResourceCallback cb, EngineJob<?> engineJob) {
this.cb = cb;
this.engineJob = engineJob;
}
public void cancel() {
synchronized (Engine.this) {
engineJob.removeCallback(cb);
}
}
}
EngineJob
EngineJob虽然叫job但是并没有实现Runnable接口,在start启动了decodeJob
//EngineJob.java
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor =
decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
executor.execute(decodeJob);
}
DecodeJob
EngineJob其实仅仅是对DecodeJob的包裹,真正实现请求的地方在DecodeJob。DecodeJob实现了Runnable接口,由线程执行器调度启动。
//DecodeJob.java
public void run() {
...
DataFetcher<?> localFetcher = currentFetcher;
try {
if (isCancelled) {
notifyFailed();
return;
}
runWrapped();
...
} 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,又调用了getNextStage方法,这里用到了两个设计模式:责任链模式和策略模式。
runReason,执行任务的原因,三种枚举值:
- INITIALIZE:第一次调度任务
- WITCH_TO_SOURCE_SERVICE:本地缓存策略失败,尝试重新获取数据,两种情况;当stage为Stage.SOURCE,或者获取数据失败并且执行和回调发生在了不同的线程
- DECODE_DATA:获取数据成功,但执行和回调不在同一线程,希望回到自己的线程去处理数据
getNextStage:获取下一步的状态
- INITIALIZE:初始化状态
- RESOURCE_CACHE:从缓存资源加载
- DATA_CACHE:从缓存数据加载
- SOURCE:从源加载获取
- ENCODE:加载完成后编码成需要的资源
- FINISHED:完成
getNextGenerator:获取下一个Generator
- ResourceCacheGenerator :尝试从修改过的资源缓存中获取,如果缓存未命中,尝试从DATA_CACHE中获取
- DataCacheGenerator 尝试从未修改过的本地缓存中获取数据,如果缓存未命中则尝试从SourceGenerator中获取
- SourceGenerator 从原始的资源中获取,可能是服务器,也可能是本地的一些原始资源
//DecodeJob.java
private void runWrapped() {
switch (runReason) {
//首次runReason默认是INITIALIZE
case INITIALIZE:
//返回Stage.RESOURCE_CACHE
stage = getNextStage(Stage.INITIALIZE);
//
currentGenerator = getNextGenerator();
runGenerators();
break;
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
case DECODE_DATA:
decodeFromRetrievedData();
break;
default:
throw new IllegalStateException("Unrecognized run reason: " + runReason);
}
}
private DataFetcherGenerator getNextGenerator() {
switch (stage) {
case RESOURCE_CACHE:
//首次stage为RESOURCE_CACHE返回ResourceCacheGenerator实例
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);
}
}
private Stage getNextStage(Stage current) {
switch (current) {
case INITIALIZE:
//策略模式,根据不同的策略返回不同的结果,默认是ALL那个实例
return diskCacheStrategy.decodeCachedResource()
? Stage.RESOURCE_CACHE
: getNextStage(Stage.RESOURCE_CACHE);
case RESOURCE_CACHE:
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 void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
//首次currentGenerator为ResourceCacheGenerator
while (!isCancelled
&& currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
//只要返回的isStarted不是true,就不断的去下一个阶段找
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
if (stage == Stage.SOURCE) {
//当stage为Stage.SOURCE的时候表示需要去请求数据,这个时候调用reschedule
reschedule(RunReason.SWITCH_TO_SOURCE_SERVICE);
return;
}
}
// We've run out of stages and generators, give up.
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
// Otherwise a generator started a new load and we expect to be called back in
// onDataFetcherReady.
}
以上请求对于我们首次加载的网络图片,最终会走到SourceGenerator的startNext()方法,startNext()又调用到startNextLoad()方法
//SourceGenerator.java
public boolean startNext() {
...
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;
startNextLoad(loadData);
}
}
return started;
}
private void startNextLoad(final LoadData<?> toStart) {
loadData.fetcher.loadData(
helper.getPriority(),
new DataCallback<Object>() {
@Override
public void onDataReady(@Nullable Object data) {
if (isCurrentRequest(toStart)) {
onDataReadyInternal(toStart, data);
}
}
@Override
public void onLoadFailed(@NonNull Exception e) {
if (isCurrentRequest(toStart)) {
onLoadFailedInternal(toStart, e);
}
}
});
}
这里关于数据加载过程,这里暂时不再深入,后面有时间再深入。最终看回调是到了onDataReadyInternal,
//SourceGenerator.java
void onDataReadyInternal(LoadData<?> loadData, 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. Then once we're back on Glide's thread, we'll
// get called again and we can write the retrieved data to cache.
cb.reschedule();
} else {
cb.onDataFetcherReady(
loadData.sourceKey,
data,
loadData.fetcher,
loadData.fetcher.getDataSource(),
originalKey);
}
}
上面如果磁盘缓存策略认为这个资源是可以被缓存的,执行写入磁盘缓存的操作。具体怎么执行的感兴趣的朋友可以看看。有点绕,不过就像方法名起的那样再次执行,多走了一次圈罢了。又回到DecodeJob的onDataFetcherReady将数据解码出来
public void onDataFetcherReady(
Key sourceKey, Object data, DataFetcher<?> fetcher, DataSource dataSource, Key attemptedKey) {
this.currentSourceKey = sourceKey;
this.currentData = data;
this.currentFetcher = fetcher;
this.currentDataSource = dataSource;
this.currentAttemptingKey = attemptedKey;
this.isLoadingFromAlternateCacheKey = sourceKey != decodeHelper.getCacheKeys().get(0);
if (Thread.currentThread() != currentThread) {
reschedule(RunReason.DECODE_DATA);
} else {
GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
try {
decodeFromRetrievedData();
} finally {
GlideTrace.endSection();
}
}
}
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 {
//解码过程这里暂不分析
resource = decodeFromData(currentFetcher, currentData, currentDataSource);
} catch (GlideException e) {
e.setLoggingDetails(currentAttemptingKey, currentDataSource);
throwables.add(e);
}
if (resource != null) {
//解码资源不为空,通知
notifyEncodeAndRelease(resource, currentDataSource, isLoadingFromAlternateCacheKey);
} else {
runGenerators();
}
}
private void notifyEncodeAndRelease(
Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
GlideTrace.beginSection("DecodeJob.notifyEncodeAndRelease");
try {
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, isLoadedFromAlternateCacheKey);
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();
} finally {
GlideTrace.endSection();
}
}
//通知完成
private void notifyComplete(
Resource<R> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
setNotifiedOrThrow();
//最终调用callback的onResourceReady
callback.onResourceReady(resource, dataSource, isLoadedFromAlternateCacheKey);
}
这里最终又调用回EngineJob的onResourceReady方法,最终调用到Engine.load方法执行的时候传入的ResourceCallback的onResourceReady。也就是SingleRequest的实现的onResourceReady方法
//EngineJob.java
private class CallResourceReady implements Runnable {
private final ResourceCallback cb;
CallResourceReady(ResourceCallback cb) {
this.cb = cb;
}
@Override
public void run() {
// Make sure we always acquire the request lock, then the EngineJob lock to avoid deadlock
// (b/136032534).
synchronized (cb.getLock()) {
synchronized (EngineJob.this) {
if (cbs.contains(cb)) {
// Acquire for this particular callback.
engineResource.acquire();
callCallbackOnResourceReady(cb);
removeCallback(cb);
}
decrementPendingCallbacks();
}
}
}
}
上面内容有些复杂,我把核心链路画了个图来帮助理解
如何把请求结果显示到ImageView上
前面分析到,请求的结果最终回调到SingleRequest的实现的onResourceReady方法中
public void onResourceReady(
Resource<?> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
stateVerifier.throwIfRecycled();
Resource<?> toRelease = null;
try {
synchronized (requestLock) {
loadStatus = null;
if (resource == null) {
//resource为空,抛异常
GlideException exception =new GlideException(...);
onLoadFailed(exception);
return;
}
Object received = resource.get();
if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
toRelease = resource;
this.resource = null;
//抛异常
GlideException exception =new GlideException(...);
onLoadFailed(exception);
return;
}
if (!canSetResource()) {
toRelease = resource;
this.resource = null;
// We can't put the status to complete before asking canSetResource().
status = Status.COMPLETE;
GlideTrace.endSectionAsync(TAG, cookie);
return;
}
//调用复写的onResourceReady方法
onResourceReady(
(Resource<R>) resource, (R) received, dataSource, isLoadedFromAlternateCacheKey);
}
} finally {
if (toRelease != null) {
engine.release(toRelease);
}
}
}
private void onResourceReady(
Resource<R> resource, R result, DataSource dataSource, boolean isAlternateCacheKey) {
// We must call isFirstReadyResource before setting status.
boolean isFirstResource = isFirstReadyResource();
status = Status.COMPLETE;
this.resource = resource;
...
notifyRequestCoordinatorLoadSucceeded();
isCallingCallbacks = true;
try {
boolean anyListenerHandledUpdatingTarget = false;
if (requestListeners != null) {
for (RequestListener<R> listener : requestListeners) {
anyListenerHandledUpdatingTarget |=
listener.onResourceReady(result, model, target, dataSource, isFirstResource);
if (listener instanceof ExperimentalRequestListener) {
ExperimentalRequestListener<R> experimentalRequestListener =
(ExperimentalRequestListener<R>) listener;
anyListenerHandledUpdatingTarget |=
experimentalRequestListener.onResourceReady(
result, model, target, dataSource, isFirstResource, isAlternateCacheKey);
}
}
}
anyListenerHandledUpdatingTarget |=
targetListener != null
&& targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);
if (!anyListenerHandledUpdatingTarget) {
Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
//调用target的onResourceReady方法
target.onResourceReady(result, animation);
}
} finally {
isCallingCallbacks = false;
}
GlideTrace.endSectionAsync(TAG, cookie);
}
//ImageViewTarget.java
public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
if (transition == null || !transition.transition(resource, this)) {
setResourceInternal(resource);
} else {
maybeUpdateAnimatable(resource);
}
}
private void setResourceInternal(@Nullable Z resource) {
// Order matters here. Set the resource first to make sure that the Drawable has a valid and
// non-null Callback before starting it.
setResource(resource);
maybeUpdateAnimatable(resource);
}
protected abstract void setResource(@Nullable Z resource);
还记得上面target的构造过程吗,ImageViewTarget有几个实现类,其中就是BitmapImageViewTarget和DrawableImageViewTarget,这里构建的是BitmapImageViewTarget, 我们看下setResource的实现
protected void setResource(Bitmap resource) {
//最终调用View的setImageBitmap方法
view.setImageBitmap(resource);
}
如何感知生命周期
还记得前面RequestManager构造的时候有三种情况,context,FragmentActivity,Fragment。对于FragmentActivity,Fragment,构造的时候会分别传入activity.getLifecycle(),fragment.getLifecycle()。
RequestManager getOrCreate(
Context context,
Glide glide,
final Lifecycle lifecycle,
FragmentManager childFragmentManager,
boolean isParentVisible) {
Util.assertMainThread();
RequestManager result = getOnly(lifecycle);
if (result == null) {
//先生成一个LifecycleLifecycle把上面传进来的Lifecycle作为参数
LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
result =
factory.build(
glide,
glideLifecycle,
new SupportRequestManagerTreeNode(childFragmentManager),
context);
lifecycleToRequestManager.put(lifecycle, result);
glideLifecycle.addListener(
new LifecycleListener() {
@Override
public void onStart() {}
@Override
public void onStop() {}
@Override
public void onDestroy() {
lifecycleToRequestManager.remove(lifecycle);
}
});
// This is a bit of hack, we're going to start the RequestManager, but not the
// corresponding Lifecycle. It's safe to start the RequestManager, but starting the
// Lifecycle might trigger memory leaks. See b/154405040
if (isParentVisible) {
result.onStart();
}
}
return result;
}
LifecycleLifecycle比较简单,就是新建了一个Set lifecycleListeners,然后addListener的时候把传进来的LifecycleListener存储到lifecycleListeners里面。LifecycleLifecycle构造方法中会把本身绑定到Android系统的androidx.lifecycle.Lifecycle监听
final class LifecycleLifecycle implements Lifecycle, LifecycleObserver {
@NonNull
private final Set<LifecycleListener> lifecycleListeners = new HashSet<LifecycleListener>();
@NonNull private final androidx.lifecycle.Lifecycle lifecycle;
LifecycleLifecycle(androidx.lifecycle.Lifecycle lifecycle) {
this.lifecycle = lifecycle;
lifecycle.addObserver(this);
}
@OnLifecycleEvent(Event.ON_START)
public void onStart(@NonNull LifecycleOwner owner) {
//通知所有的LifecycleListener,Util.getSnapshot是为了线程安全,每次都copy出一份
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
@OnLifecycleEvent(Event.ON_STOP)
public void onStop(@NonNull LifecycleOwner owner) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
@OnLifecycleEvent(Event.ON_DESTROY)
public void onDestroy(@NonNull LifecycleOwner owner) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
owner.getLifecycle().removeObserver(this);
}
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (lifecycle.getCurrentState() == State.DESTROYED) {
listener.onDestroy();
} else if (lifecycle.getCurrentState().isAtLeast(State.STARTED)) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
}
RequestManager(...) {
...
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
//这里将RequestManager实例添加到lifecycle的监听器集合中
lifecycle.addListener(this);
}
...
}
如何监控网络变化
前面分析监控生命周期的时候,注意到一个connectivityMonitor也被添加到生命周期监控集合中
RequestManager(...) {
...
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
...
//这里将connectivityMonitor添加到lifecycle的监听器集合中
lifecycle.addListener(connectivityMonitor);
...
}
ConnectivityMonitorFactory的实现只有一个DefaultConnectivityMonitorFactory,我们去看它的build方法
public class DefaultConnectivityMonitorFactory implements ConnectivityMonitorFactory {
private static final String TAG = "ConnectivityMonitor";
private static final String NETWORK_PERMISSION = "android.permission.ACCESS_NETWORK_STATE";
@NonNull
@Override
public ConnectivityMonitor build(
@NonNull Context context, @NonNull ConnectivityMonitor.ConnectivityListener listener) {
int permissionResult = ContextCompat.checkSelfPermission(context, NETWORK_PERMISSION);
boolean hasPermission = permissionResult == PackageManager.PERMISSION_GRANTED;
...
return hasPermission
? new DefaultConnectivityMonitor(context, listener)
: new NullConnectivityMonitor();
}
}
这里主要新建了一个DefaultConnectivityMonitor,因为NullConnectivityMonitor是没有权限的时候才去新建的,方法都是空实现。
final class DefaultConnectivityMonitor implements ConnectivityMonitor {
private final Context context;
@SuppressWarnings("WeakerAccess")
@Synthetic
final ConnectivityListener listener;
DefaultConnectivityMonitor(@NonNull Context context, @NonNull ConnectivityListener listener) {
this.context = context.getApplicationContext();
this.listener = listener;
}
private void register() {
SingletonConnectivityReceiver.get(context).register(listener);
}
private void unregister() {
SingletonConnectivityReceiver.get(context).unregister(listener);
}
@Override
public void onStart() {
register();
}
@Override
public void onStop() {
unregister();
}
@Override
public void onDestroy() {
// Do nothing.
}
}
核心就是在onStart()注册一个监听,在onStop()取消注册监听。SingletonConnectivityReceiver是个单例模式实现的网络状态监听器。
final class SingletonConnectivityReceiver {
private static volatile SingletonConnectivityReceiver instance;
@GuardedBy("this")
@Synthetic
final Set<ConnectivityListener> listeners = new HashSet<ConnectivityListener>();
//单例模式实现SingletonConnectivityReceiver
static SingletonConnectivityReceiver get(@NonNull Context context) {
if (instance == null) {
synchronized (SingletonConnectivityReceiver.class) {
if (instance == null) {
instance = new SingletonConnectivityReceiver(context.getApplicationContext());
}
}
}
return instance;
}
private SingletonConnectivityReceiver(final @NonNull Context context) {
GlideSupplier<ConnectivityManager> connectivityManager =
GlideSuppliers.memorize(
new GlideSupplier<ConnectivityManager>() {
@Override
public ConnectivityManager get() {
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
});
ConnectivityListener connectivityListener =
new ConnectivityListener() {
@Override
public void onConnectivityChanged(boolean isConnected) {
//网络状态发生变化的时候通知所有的listeners
Util.assertMainThread();
List<ConnectivityListener> toNotify;
synchronized (SingletonConnectivityReceiver.this) {
toNotify = new ArrayList<>(listeners);
}
for (ConnectivityListener listener : toNotify) {
listener.onConnectivityChanged(isConnected);
}
}
};
frameworkConnectivityMonitor =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
? new FrameworkConnectivityMonitorPostApi24(connectivityManager, connectivityListener)
: new FrameworkConnectivityMonitorPreApi24(
context, connectivityManager, connectivityListener);
}
synchronized void register(ConnectivityListener listener) {
listeners.add(listener);
maybeRegisterReceiver();
}
/**
* To avoid holding a lock while notifying listeners, the unregistered listener may still be
* notified about a connectivity change after this method completes if this method is called on a
* thread other than the main thread and if a connectivity broadcast is racing with this method.
* Callers must handle this case.
*/
synchronized void unregister(ConnectivityListener listener) {
listeners.remove(listener);
maybeUnregisterReceiver();
}
...
}
用到哪些设计模式
- 单例模式
- 建造者模式
- 外观模式
- 享元模式
- 原型模式
- 观察者模式
- 简单工厂
- 工厂方法
- 责任链模式
- 策略模式
参考链接
https://juejin.cn/post/7044079102839488543?searchId=202410100927002AB04F7243D94B6586AA
https://blog.csdn.net/Love667767/article/details/106576888/
https://www.cnblogs.com/android-blogs/p/5735655.htmlun