Glide 源码分析之流程

摘要

Glide流程三步曲withloadinto三个函数,完成一次Glide请求。with的主要工作是首次创建Glide单例,并装配Glide各种配置参数和创建相关实例,这些都会在into函数中被使用到,第二个要点就是与Fragment的生命周期绑定,让Glide请求能感应到生命周期的变化,从而可以进行暂停,恢复,发起请求的一下操作。load函数则是构建本次Glide请求的相关信息,例如RequestBuilderRequestOptions等。into函数则是Glide的核心,包括缓存,解码,采样转化,资源获取等等。

Glide源码分析基于Glide 4.12.0:

1
2
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

由于源码分析阶段会有很多分支,很多的类型,所以在一些点会基于下面例子分析。

1
2
val url="http//:www.xxm-sz.githu.io/test.png"
Glide.with(this).load(url).into(imageView)

with函数

Glide单例的创建

Glide.with有很多重载函数。这里以Activity为例分析。

1
2
3
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}

Glide.with的所有重载函数中的getRetriever都是调用getRetriever来生成Glide单例。

1
2
3
4
5
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
......
return Glide.get(context).getRequestManagerRetriever();
}

Glide.get(context)通过双重检查实现单例模式,生成Glide实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static Glide get(@NonNull Context context) {
if (glide == null) {
//步骤1
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
//步骤2
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}

return glide;
}

Application 模块中,可创建一个添加有 @GlideModule 注解,继承自 AppGlideModule 的类,这样就可以通过流式API使用Glide。GeneratedAppGlideModule也就是对应该注解类的。

步骤1: getAnnotationGeneratedGlideModules函数主要通过反射获取我们AppGlideModule实例。

1
2
3
4
5
6
7
8
9
10
11
private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules(Context context) {
GeneratedAppGlideModule result = null;
...
Class<GeneratedAppGlideModule> clazz =
(Class<GeneratedAppGlideModule>)
Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
result =
clazz.getDeclaredConstructor(Context.class).newInstance(context.getApplicationContext());
...
return result;
}

步骤2: checkAndInitializeGlide函数最终会调用到initializeGlide函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
//通过AndroidManifest文件解析Module
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
//将AndroidManifest文件解析到的所有Module中剔除掉通过注解获取到的Module
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;
}
iterator.remove();
}
}

...

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);
}
//通过GildeBuilder构建出Glide
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
try {
module.registerComponents(applicationContext, glide, glide.registry);
} catch (AbstractMethodError e) {
...
}
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}

其实在没有定义GlideModule情况下,这段代码只有一个核心点,通过GlideBuilder构建Glide,为Glide创建默认的属性,例如缓存,引擎等等。创建的对象在后续into函数中被大量使用到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
Glide build(@NonNull Context context) {
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();
}

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 requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory, experiments);

return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
experiments);
}

RequestManager的创建

RequestManager的创建涉及到与ApplicationFragment生命周期的绑定,RequestManager可以用来开始和停止、管理本次Glide请求。

再回到getRetriever(activity).get(activity)get函数。

1
2
3
4
5
6
7
8
9
10
11
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}

通过Util.isOnBackgroundThread()判断是否后台线程,如果不是则通过supportFragmentGet创建RequestManager。否则通过get(activity)的重载函数get(Context)获取RequestManager。查看get()的其他重载函数,如果在后台线程或者参数为ApplicationContext上下文,都通过getApplicationManager(context)来生成RequestManager,而其他情况则是supportFragmentGet函数。

supportFragmentGet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
//步骤1:获取SupportRequestManagerFragment
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
//步骤2:获取RequestManager
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}

步骤1:通过getSupportRequestManagerFragment函数创建SupportRequestManagerFragment对象。SupportRequestManagerFragmentFragment的子类,该Fragment对象是没有视图,作为发起Glide请求的ActivityFragment的子Fragment,将持有RequestManager实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
//tag查找
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//HashMap查找
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//新建
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}

先通过FRAGMENT_TAG标签在FragmentMananger中查找是否有已添加的Fragment实例。没有的话,在endingSupportRequestManagerFragments查找,endingSupportRequestManagerFragmentsHashMap类型的,以FragmentManangerkeySupportRequestManagerFragmentValue。没有的话,则新建实例,并添加pendingSupportRequestManagerFragments中,并通过FragmentMananger提交。这个创建逻辑也保证了在一个Activity中所发起的所有Glide请求都只有一个空白Fragment

在创建SupportRequestManagerFragment时候,会创建一个新的ActivityFragmentLifecycle,用于跟踪和监听Fragment的生命周期事件。

**步骤2:**在步骤1获取到了Fragment后,获取其持有的RequestManager,如果Fragment是新建获得,那肯定是没有,只能通过新建RequestManager

1
factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);

这里的factoryRequestManagerFactory,在构建Glide单例的时候会创建,默认情况下是DEFAULT_FACTORY。在创建RequestManager时不仅监听Fragment生命周期的变化,还会监听网络连接变化。

1
2
3
4
5
6
7
8
9
10
11
12
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) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};

所以,当Fragment生命周期发生变化或者网络发生变化时,RequestManager根据不同场景去管理本次Glide请求。

View场景下的Glide.with()稍微麻烦点,需要根据View.getContext()得到Context的类型,去查找不同的get()函数重载。而Fragment场景下,与Actvity发起的Glide请求大同小异。

getApplicationManager

在后台线程或ApplicationContext场景下,通过getApplicationManager(context)创建RequestManager。通过下面代码可以看到,RequestManager直接与Application的生命周期绑定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private RequestManager getApplicationManager(@NonNull Context context) {
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}

return applicationManager;
}

ApplicationLifecycle基本什么都没做,因为Glide请求与Application绑定,意味随着Applilcation的消亡而消亡。

到这里,Glide.with()的分析就完毕了,主要创建Glide单例,和为Glide请求创建RequestManager。在后台线程或者ApplicationContext情况下创建的RequestManager是与Application的生命周期绑定的,而其他情况下,通过创建一个无视图的Fragment的,并将RequestManager与其生命周期绑定。

配置:load

load函数也有很多重载函数。

1
2
3
public RequestBuilder<XXX> load(@Nullable XXX xxx) {
return asDrawable().load(xxx);
}

所以看一下asDrawable()函数。

1
2
3
4
5
6
7
8
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}

public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}

可见,asDrawable函数主要是创建了RequestBuilder对象,RequestBuilderBaseRequestOptions的子类,用于保存Glide通用资源类型的配置参数。BaseRequestOptions的另外一个子类RequestOptions,通常用来配置一次独立的Glide请求配置参数。注意这里的as的参数Drawable.class,表明的是本次请求的目标资源是Drawable.class,即后续分析会看到transcodeClass就是该Drawable.class。仅下载情况是File.class,Gif图情况下是GifDrawable.class

继续看RequestBuilderload函数。

1
2
3
4
5
6
7
8
9
10
11
12
public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}

private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
if (isAutoCloneEnabled()) {
return clone().loadGeneric(model);
}
this.model = model;
isModelSet = true;
return selfOrThrowIfLocked();
}

主要是将我们设置的资源:Glide.with(context).load(xxx)中的xxx设置给RequestBuildermodel属性,并将isModelSet设置true。后续分析中modelClass就是这里xxx的类型。

假如这里load(drawable)或者load(bitmap),会有多一个步骤:

1
2
3
public RequestBuilder<TranscodeType> load(@Nullable Drawable drawable) {
return loadGeneric(drawable).apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}

也就是多了apply(options),跟我们自定义Glide请求配置是一致的。这里也会将RequestOptions缓存起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
public T apply(@NonNull BaseRequestOptions<?> o) {
if (isAutoCloneEnabled) {
return clone().apply(o);
}
BaseRequestOptions<?> other = o;

if (isSet(other.fields, SIZE_MULTIPLIER)) {
sizeMultiplier = other.sizeMultiplier;
}
if (isSet(other.fields, USE_UNLIMITED_SOURCE_GENERATORS_POOL)) {
useUnlimitedSourceGeneratorsPool = other.useUnlimitedSourceGeneratorsPool;
}
if (isSet(other.fields, USE_ANIMATION_POOL)) {
useAnimationPool = other.useAnimationPool;
}
if (isSet(other.fields, DISK_CACHE_STRATEGY)) {
diskCacheStrategy = other.diskCacheStrategy;
}
if (isSet(other.fields, PRIORITY)) {
priority = other.priority;
}
if (isSet(other.fields, ERROR_PLACEHOLDER)) {
errorPlaceholder = other.errorPlaceholder;
errorId = 0;
fields &= ~ERROR_ID;
}
if (isSet(other.fields, ERROR_ID)) {
errorId = other.errorId;
errorPlaceholder = null;
fields &= ~ERROR_PLACEHOLDER;
}
if (isSet(other.fields, PLACEHOLDER)) {
placeholderDrawable = other.placeholderDrawable;
placeholderId = 0;
fields &= ~PLACEHOLDER_ID;
}
if (isSet(other.fields, PLACEHOLDER_ID)) {
placeholderId = other.placeholderId;
placeholderDrawable = null;
fields &= ~PLACEHOLDER;
}
if (isSet(other.fields, IS_CACHEABLE)) {
isCacheable = other.isCacheable;
}
if (isSet(other.fields, OVERRIDE)) {
overrideWidth = other.overrideWidth;
overrideHeight = other.overrideHeight;
}
if (isSet(other.fields, SIGNATURE)) {
signature = other.signature;
}
if (isSet(other.fields, RESOURCE_CLASS)) {
resourceClass = other.resourceClass;
}
if (isSet(other.fields, FALLBACK)) {
fallbackDrawable = other.fallbackDrawable;
fallbackId = 0;
fields &= ~FALLBACK_ID;
}
if (isSet(other.fields, FALLBACK_ID)) {
fallbackId = other.fallbackId;
fallbackDrawable = null;
fields &= ~FALLBACK;
}
if (isSet(other.fields, THEME)) {
theme = other.theme;
}
if (isSet(other.fields, TRANSFORMATION_ALLOWED)) {
isTransformationAllowed = other.isTransformationAllowed;
}
if (isSet(other.fields, TRANSFORMATION_REQUIRED)) {
isTransformationRequired = other.isTransformationRequired;
}
if (isSet(other.fields, TRANSFORMATION)) {
transformations.putAll(other.transformations);
isScaleOnlyOrNoTransform = other.isScaleOnlyOrNoTransform;
}
if (isSet(other.fields, ONLY_RETRIEVE_FROM_CACHE)) {
onlyRetrieveFromCache = other.onlyRetrieveFromCache;
}

// Applying options with dontTransform() is expected to clear our transformations.
if (!isTransformationAllowed) {
transformations.clear();
fields &= ~TRANSFORMATION;
isTransformationRequired = false;
fields &= ~TRANSFORMATION_REQUIRED;
isScaleOnlyOrNoTransform = true;
}

fields |= other.fields;
options.putAll(other.options);//缓存RequestOptions

return selfOrThrowIfLocked();
}

也就是说load函数的主要工作是配置Glide请求的一些参数。

核心:into

into函数也有很多重载函数,但我们最常用的就是into(ImageView)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView 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());
}

从这里看到Glide只处理View ScaleTypeCENTER_CROPCENTER_INSIDE、 FIT_XY,而FIT_CENTERFIT_STARTFIT_END都统一通过optionalFitCenter处理,而CENTERMATRIX则直接忽略。然后调用into另外一个重载函数。先通过glideContext.buildImageViewTargetImageView封装成ViewTarget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}

public class ImageViewTargetFactory {
@NonNull
@SuppressWarnings("unchecked")
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)");
}
}
}

通过ImageViewTargetFactory工厂的buildTarget函数可以发现ViewTarget有两种类型:BitmapImageViewTragetDrawableImageViewTarget。两者都是ImageViewTarget的子类,前者用于展示Bitmap,后者用于展示Drawable。另外一个子类ThumbnailImageViewTarget,用于在固定尺寸的ImageView展示多张图片,避免额外调用requestLayout,常用场景就是列表的缩略图设置。

into函数的第三个参数Executors.mainThreadExecutor(),在主线程执行的线程池,也就是调用线程池的execute函数时,将runable对象通过handler post到主线程的队列,这样就在主线程执行了该任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static Executor mainThreadExecutor() {
return MAIN_THREAD_EXECUTOR;
}

public static Executor mainThreadExecutor() {
return MAIN_THREAD_EXECUTOR;
}

private static final Executor MAIN_THREAD_EXECUTOR =
new Executor() {
@Override
public void execute(@NonNull Runnable command) {
Util.postOnUiThread(command);
}
};

public static void postOnUiThread(Runnable runnable) {
getUiThreadHandler().post(runnable);
}

private static Handler getUiThreadHandler() {
if (mainThreadHandler == null) {
synchronized (Util.class) {
if (mainThreadHandler == null) {
mainThreadHandler = new Handler(Looper.getMainLooper());
}
}
}
return mainThreadHandler;
}

继续看看into的重载函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
//步骤1
Request request = buildRequest(target, targetListener, options, callbackExecutor);
//查看view的tag是否设置了Request
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}

requestManager.clear(target);
target.setRequest(request);
//步骤2
requestManager.track(target, request);

return target;
}

步骤1: 通过buildRequest创建了Request对象,Request代表了一次为目标Target加载图片资源resourceGlide请求。

SingleRequest的创建

通过buildRequest函数会创建一个Request对象,该对象是Request的子类实例,可能ThumbnailRequestCoordinatorErrorRequestCoordinator也有可能是SingleRequest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private Request buildRequest(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(
/*requestLock=*/ new Object(),
target,
targetListener,
/*parentCoordinator=*/ null,
transitionOptions,
requestOptions.getPriority(),
requestOptions.getOverrideWidth(),
requestOptions.getOverrideHeight(),
requestOptions,
callbackExecutor);
}

调用了buildRequestRecursive函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
private Request buildRequestRecursive(
Object requestLock,
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.
ErrorRequestCoordinator errorRequestCoordinator = null;
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
//步骤A
Request mainRequest =
buildThumbnailRequestRecursive(
requestLock,
targ et,
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(
requestLock,
target,
targetListener,
errorRequestCoordinator,
errorBuilder.transitionOptions,
errorBuilder.getPriority(),
errorOverrideWidth,
errorOverrideHeight,
errorBuilder,
callbackExecutor);
errorRequestCoordinator.setRequests(mainRequest, errorRequest);
return errorRequestCoordinator;
}

步骤A: buildThumbnailRequestRecursive创建了Request,这里返回的Request有两种可能,一种是设置了加载缩略图和主图的,返回的ThumbnailRequestCoordinator,会协调好缩略图SingleRequest和主图SingleRequest的同时加载。另外一种是SingleRequest,单单加载主图,两者都是Request的子类。

如果有设置在发生错误时的请求也会在这里配置该请求,通过后面的分析,也就是每个RequestBuilder(不仅是主图,也可以是缩略图,错误提示图等)都会创建一个SingleRequest

接着看buildThumbnailRequestRecursive函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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) {
//由于没有设置缩略图,直接走else分支
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;

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(requestLock, parentCoordinator);
Request fullRequest =
obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
isThumbnailBuilt = true;
//调用了thumbnailBuilder.buildRequestRecursive,此时是没有设置缩略图的,直接走else分支,返回了SingleRequest
Request thumbRequest =
thumbnailBuilder.buildRequestRecursive(
requestLock,
target,
targetListener,
coordinator,
thumbTransitionOptions,
thumbPriority,
thumbOverrideWidth,
thumbOverrideHeight,
thumbnailBuilder,
callbackExecutor);
isThumbnailBuilt = false;
coordinator.setRequests(fullRequest, thumbRequest);
return coordinator;
} else if (thumbSizeMultiplier != null) {
//缩略因子
ThumbnailRequestCoordinator coordinator =
new ThumbnailRequestCoordinator(requestLock, parentCoordinator);
Request fullRequest =
obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
BaseRequestOptions<?> thumbnailOptions =
requestOptions.clone().sizeMultiplier(thumbSizeMultiplier);

Request thumbnailRequest =
obtainRequest(
requestLock,
target,
targetListener,
thumbnailOptions,
coordinator,
transitionOptions,
getThumbnailPriority(priority),
overrideWidth,
overrideHeight,
callbackExecutor);

coordinator.setRequests(fullRequest, thumbnailRequest);
return coordinator;
} else {
// Base case: no thumbnail.
return obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
}

由于没有设置缩略图,直接走else分支,通过obtainRequest获得Request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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);
}
}

通过SingleRequest.obtain函数返回了Request对象。obtain函数直接创建了Request的子类SingleRequest对象。

这里buildRequest函数小结一下:

  • 如果设置了缩略图,返回ThumbnailRequestCoordinator对象,包含了主图和缩图两个独立的SingleRequest
  • 如果设置了错误占位图,返回的是ErrorRequestCoordinator,包含了上一步返回的Request对象和占位图的SingleRequest对象,
  • 如果上两步都没有设置,返回主图的SingleRequest

继续分析into函数的步骤2:

requestManager.track

track函数分别用了TragetTrackRequestTrack跟踪本次请求的tragetrequest对象。RequestTrack主要用于跟踪,取消和重启正在运行中的,已完成或者失败的请求。TragetTrack则持有当前活跃的RequestManager以及转发绑定的生命周期事件。

1
2
3
4
5
6
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
//将Traget存放到set中
targetTracker.track(target);
//开始请求
requestTracker.runRequest(request);
}

看看RequestTrackrunRequest函数。

1
2
3
4
5
6
7
8
9
10
11
12
public void runRequest(@NonNull Request request) {
requests.add(request);
if (!isPaused) {//首次创建肯定是false
request.begin();
} else {
request.clear();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Paused, delaying request");
}
pendingRequests.add(request);
}
}

看看request.begin()函数。我们这里直接定位到SingleRequestbegin函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
public void begin() {
synchronized (requestLock) {
......
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());
}
}
}

定位到target.getSize(this)获取Target尺寸大小,这里的thisSizeReadyCallback。也就是在获取到目标尺寸之后,通过SizeReadyCallback对象回调。这里的Target对象直接定位到ViewTarget

1
2
3
public void getSize(@NonNull SizeReadyCallback cb) {
sizeDeterminer.getSize(cb);
}

通过getSize函数的注释,就知道了Glide如何去获取尺寸的。

  • 直接获取View的宽高,如果都大于零或者等于原始尺寸,说明已经能获取到了。
  • 直接获取View的LayotuParams,如果都大于零或者等于原始尺寸,说明已经能获取到了。
  • 添加addOnPreDrawListener监听。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void getSize(@NonNull SizeReadyCallback cb) {
int currentWidth = getTargetWidth();
int currentHeight = getTargetHeight();
if (isViewStateAndSizeValid(currentWidth, currentHeight)) {
cb.onSizeReady(currentWidth, currentHeight);
return;
}

// We want to notify callbacks in the order they were added and we only expect one or two
// callbacks to be added a time, so a List is a reasonable choice.
if (!cbs.contains(cb)) {
cbs.add(cb);
}
if (layoutListener == null) {
ViewTreeObserver observer = view.getViewTreeObserver();
layoutListener = new SizeDeterminerLayoutListener(this);
observer.addOnPreDrawListener(layoutListener);
}
}

所以通过三个步骤,最终会获得ViewTarget的宽高,并通过SizeReadyCallback对象的onSizeReady函数回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Override
public void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
synchronized (requestLock) {

if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;

float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);

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);

if (status != Status.RUNNING) {
loadStatus = null;
}
}
}

所以onSizeReady最重要的点就是调用了engine.load开始本次Glide请求。

engine.load

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public <R> LoadStatus load(
GlideContext glideContext,
Object model,
Key signature,
int width,
int height,
Class<?> resourceClass,
Class<R> transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map<Class<?>, Transformation<?>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
Options options,
boolean isMemoryCacheable,
boolean useUnlimitedSourceExecutorPool,
boolean useAnimationPool,
boolean onlyRetrieveFromCache,
ResourceCallback cb,
Executor callbackExecutor) {
long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;

EngineKey key =
keyFactory.buildKey(
model,
signature,
width,
height,
transformations,
resourceClass,
transcodeClass,
options);

EngineResource<?> memoryResource;
synchronized (this) {
//步骤1
memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

if (memoryResource == null) {
//步骤2
return waitForExistingOrStartNewJob(
glideContext,
model,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
options,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache,
cb,
callbackExecutor,
key,
startTime);
}
}
cb.onResourceReady(
memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
return null;
}

步骤1:调用loadFromMemory函数从内存获取缓存,如果没有拿到缓存资源,则通过步骤2:waitForExistingOrStartNewJob函数从磁盘缓存或者网络获取。下节再分享这里的Glide缓存。最后拿到资源,则通过cb.onResourceReady函数回调,回到SingleRequest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void onResourceReady(
Resource<?> resource, DataSource dataSource, boolean isLoadedFromAlternateCacheKey) {
stateVerifier.throwIfRecycled();
Resource<?> toRelease = null;
try {
synchronized (requestLock) {
......
onResourceReady(
(Resource<R>) resource, (R) received, dataSource, isLoadedFromAlternateCacheKey);
}
} finally {
if (toRelease != null) {
engine.release(toRelease);
}
}
}

onResourceReady这里对一些合法性的检查,然后调用onResourceReady的重载函数。

1
2
3
4
5
6
private void onResourceReady(
Resource<R> resource, R result, DataSource dataSource, boolean isAlternateCacheKey) {
...
target.onResourceReady(result, animation);
...
}

重载的onResourceReady函数这里调用targetonResourceReady函数。这里定位到ImageViewTarget类。

1
2
3
4
5
6
7
public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
if (transition == null || !transition.transition(resource, this)) {
setResourceInternal(resource);
} else {
maybeUpdateAnimatable(resource);
}
}

其实无论哪个分支,maybeUpdateAnimatable函数都会被执行,即判断当前资源是否可执行的动画。如果是的话,则直接开始执行。

1
2
3
4
5
6
7
8
private void maybeUpdateAnimatable(@Nullable Z resource) {
if (resource instanceof Animatable) {
animatable = (Animatable) resource;
animatable.start();
} else {
animatable = null;
}
}

setResourceInternal函数,先调用了setResouce函数,猜测该函数设置资源给Target。再调用maybeUpdateAnimatable函数。

1
2
3
4
private void setResourceInternal(@Nullable Z resource) {
setResource(resource);
maybeUpdateAnimatable(resource);
}

setResourceImageViewTarget是一个抽象方法,看一下它的子类BitmapImageViewTarget的实现。

1
2
3
protected void setResource(Bitmap resource) {
view.setImageBitmap(resource);
}

setResource直接将Bitmap设置给了ImageView,那么图片也即将展示出来。

因为忽略了engine.load加载资源分析,所以into函数看起来很简单,但Glide的所有核心也正在这一部分,将通过后续文章分析该部分。

总结

简简单单分析了Glide的流程三部曲,每一步是责任分明,创建单例与绑定生命周期,配置参数,开始请求。但这才刚刚开始,后续将更加枯燥无趣,黯然无色。