glide源码精髓是能学习到很多设计模式,以及对图片的各种处理,首先以源码通读的方式进入到今天的文章。
glide源码是在4.16.0的版本上分析的。
平常我们使用glide时候直接glide.with(activity).load(url).into(imageview)加载图片,基于此,我们顺藤摸瓜看下底层是怎么加载图片的。
Glide.with
我们是基于参数是activity的重载方法:
1
2
3
|
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
|
先获取RequestManagerRetriever,然后再获取RequestManager:
1
2
3
|
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
return Glide.get(context).getRequestManagerRetriever();
}
|
首先调用Glide.get(context)方法,然后通过getRequestManagerRetriever方法获取到RequestManagerRetriever:
1
2
3
4
5
6
7
8
9
10
|
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
|
可以看到该方法是一个静态方法加锁,锁的是所有线程创建glide的实例。如果glide为空,会调用checkAndInitializeGlide方法,猜测是创建glide实例的方法:

此处不允许多次初始化glide对象,通过一个布尔值控制,并且该布尔值是一个volatile类型的,在多线程中访问是安全的。接着调用了initializeGlide方法:
1
2
3
4
|
private static void initializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}
|
调用了另外一个initializeGlide方法:
1
2
3
4
5
6
7
8
9
10
|
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
//省略代码
Context applicationContext = context.getApplicationContext();
Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
|
此处省略了通过注解来生成各种配置,其中注解是GlideModule的注解,它是一个编译时注解,通过编译时扫描到该注解,然后生成GeneratedAppGlideModuleImpl类,initializeGlide是通过反射执行GeneratedAppGlideModuleImpl类。最终通过GlideBuilder.build方法来生成glide对象:
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
|
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(),
GlideExecutor.newAnimationExecutor(),
isActiveResourceRetentionAllowed);
}
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptions.lock(),
defaultTransitionOptions);
}
|
初始化线程池,构造了Engine、RequestManagerRetriever对象,最后初始化了Glide对象。所以上面的getRequestManagerRetriever方法返回的对象就是此处new的RequestManagerRetriever对象。接着调用了RequestManagerRetriever的get方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@NonNull
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
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
|
该方法会返回一个RequestManager对象,如果context不是Application类型,则通过get方法创建RequestManager对象,如果是Application类型,则通过getApplicationManager方法创建。首先来看下通过FragmentActivity来创建RequestManager对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public RequestManager get(@NonNull FragmentActivity activity) {
//如果当前不是主线程,则通过Application创建
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
}
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
boolean isActivityVisible = isActivityVisible(activity);
Glide glide = Glide.get(activity.getApplicationContext());
return lifecycleRequestManagerRetriever.getOrCreate(
activity,
glide,
activity.getLifecycle(),
activity.getSupportFragmentManager(),
isActivityVisible);
}
|
首先判断当前线程如果不是主线程,则通过Application创建RequestManager,接着判断activity是否可见,可见的条件是activity没有finish掉。最终通过LifecycleRequestManagerRetriever的getOrCreate方法来创建RequestManager:
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
|
RequestManager getOrCreate(
Context context,
Glide glide,
final Lifecycle lifecycle,
FragmentManager childFragmentManager,
boolean isParentVisible) {
Util.assertMainThread();
RequestManager result = getOnly(lifecycle);
if (result == null) {
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);
}
});
if (isParentVisible) {
result.onStart();
}
}
return result;
}
|
先通过getOnly从lifecycleToRequestManager这个map中取,key是activity的lifecycle对象,如果没有取到则通过factory.build来创建RequestManager,factory是RequestManagerFactory接口,它是在glide初始化的时候构造的。LifecycleRequestManagerRetriever中的factory是在RequestManagerRetriever构造方法中传进来的:
1
2
3
4
5
|
public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
this.factory = factory != null ? factory : DEFAULT_FACTORY;
lifecycleRequestManagerRetriever = new LifecycleRequestManagerRetriever(this.factory);
frameWaiter = buildFrameWaiter();
}
|
RequestManagerRetriever构造方法中默认传入的RequestManagerFactory是空的,因此会用DEFAULT_FACTORY:
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);
}
};
|
直接new了一个RequestManager对象,可见典型的工厂模式创建对象。
- 小结
- Glide.with方法里面判断glide单例对象是否存在,如果不存在先在GlideBuilder的build方法中创建各种线程池,包括访问资源的线程池,缓存线程池,动画线程池等。然后创建Engine和RequestManagerRetriever对象,接着把创建的各种线程池,pool,Engine和RequestManagerRetriever都传入到Glide对象中,方便后面使用。上面在构建Glide之前会判断GeneratedAppGlideModule注解的类存不存在,它是通过注解来配置各种参数的类。
- 构建完Glide对象后,接着通过RequestManagerRetriever的get方法创建RequestManager,其中创建RequestManager的方式有Application,Fragment,Activity的形式,我们拿Activity的形式创建来说,如果当前线程不是主线程,则使用Application的形式来创建,因为非主线程是不带生命周期。接着通过LifecycleRequestManagerRetriever的getOrCreate方法来获取RequestManager,此处的LifecycleRequestManagerRetriever是在RequestManagerRetriever构造方法中创建的。
- LifecycleRequestManagerRetriever的getOrCreate方法中通过map存储了Lifecycle中的RequestManager,也就是说每一个Lifecycle对应一个RequestManager。首先判断该map中是否存在RequestManager,如果不存在,创建了一个LifecycleLifecycle,它是一个LifecycleObserver对象,它通过监听Activity等类型的Lifecycle的生命周期,来管理Lifecycle和RequestManager。
- 上面就是整个Glide.with创建RequestManager的流程。
Glide.with(Context).load(url)
上面分析了Glide.with是创建RequestManager的过程,那其实load方法也就对应了RequestManager的load方法:
1
2
3
|
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
|
我们通过传进来的string作为讲解,首先调用了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);
}
|
将Drawable作为RequestBuilder的泛型,并返回了RequestBuilder实例,接着看RequestBuilder的load方法:
1
2
3
4
5
6
7
8
9
10
11
|
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();
}
|
load方法将url传给了RequestBuilder的model属性,然后返回自己。
Glide.with(Context).load(url).into(imageView)
调完load方法,实际就返回了RequestBuilder对象了。所以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
|
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
Util.assertMainThread();
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:
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/* targetListener= */ null,
requestOptions,
Executors.mainThreadExecutor());
}
|
RequestBbuilder继承自BaseRequestOptions,在into里面首先通过imageView的scaleType,然后生成不同的BaseRequestOptions,然后通过glideContext.buildImageViewTarget方法将ImageView包装成ViewTarget:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
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);
}
}
|
上面分析过clazz传进来的是Drawable.class,所以会包装成DrawableImageViewTarget。
接着调用了另外一个into方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
Request request = buildRequest(target, targetListener, options, callbackExecutor);
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);
requestManager.track(target, request);
return target;
}
|
首先调用了buildRequest方法来构建Request,然后获取target的request和当前request是不是同一个,如果是的话,则直接返回已经存在的target,否则调用requestManager.track,我们先看buildRequest:
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
|
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);
}
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) {
Request mainRequest =
buildThumbnailRequestRecursive(
requestLock,
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
return mainRequest;
}
|
上面的buildRequestRecursive方法省去了errorBuilder相关的处理,默认是不用去处理的,所以可以看到上面构建Request实际调用了buildThumbnailRequestRecursive方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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) {
return obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
|
上面也是省去了其他相关逻辑,所以我们直接看obtainRequest方法:
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
|
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);
}
public static <R> SingleRequest<R> obtain(
Context context,
GlideContext glideContext,
Object requestLock,
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) {
return new SingleRequest<>(
context,
glideContext,
requestLock,
model,
transcodeClass,
requestOptions,
overrideWidth,
overrideHeight,
priority,
target,
targetListener,
requestListeners,
requestCoordinator,
engine,
animationFactory,
callbackExecutor);
}
|
上面都没什么好说的,直接new了一个SingleRequest,此处SingleRequest的发型是Drawable,这是在上面分析load的时候知道的,先明确这点。我们再回到上面RequestBuilder的into方法,先构建一个SingleRequest,然后看当前target的request和构建的SingleRequest是不是同一个,如果是直接返回,如果不是调用requestManager.track,先看target.getRequest,前面分析过target是一个DrawableImageViewTarget,它的父父类ViewTarget:
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
|
public Request getRequest() {
Object tag = getTag();
Request request = null;
if (tag != null) {
if (tag instanceof Request) {
request = (Request) tag;
} else {
throw new IllegalArgumentException(
"You must not call setTag() on a view Glide is targeting");
}
}
return request;
}
private static int tagId = R.id.glide_custom_view_target_tag;
private Object getTag() {
return view.getTag(tagId);
}
public void setRequest(@Nullable Request request) {
setTag(request);
}
private void setTag(@Nullable Object tag) {
isTagUsedAtLeastOnce = true;
view.setTag(tagId, tag);
}
|
可以看到request是塞入到view的tag上,并且该tag是绑定了一个id。接着看下requestManager.track:
1
2
3
|
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
|
将target放到TargetTracker中:
1
2
3
4
5
|
private final Set<Target<?>> targets =
Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());
public void track(@NonNull Target<?> target) {
targets.add(target);
}
|
将target只是放到set集合中,后面会用到,先不用管。重要看RequestTracker的runRequest方法:
1
2
3
4
5
6
7
8
9
10
11
|
private final Set<Request> requests =
Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());
public void runRequest(@NonNull Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
request.clear();
pendingRequests.add(request);
}
}
|
首先将request也是放到set集合中,接着判断当前是不是pause状态,默认不是pause状态,则调用request的begin方法,前面分析过该request实际是SingleRequest:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public void begin() {
synchronized (requestLock) {
experimentalNotifyRequestStarted(model);
status = Status.WAITING_FOR_SIZE;//默认状态
//如果重写了override方法来制定加载图片的大小
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
//如果没有制定大小走此处
target.getSize(this);
}
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
//回调start的状态
target.onLoadStarted(getPlaceholderDrawable());
}
}
}
|
如果没有通过override方法制定加载图片的大小,则调用target.getSize方法:
1
2
3
|
public void getSize(@NonNull SizeReadyCallback cb) {
sizeDeterminer.getSize(cb);
}
|
调用了内部类SizeDeterminer的getSize方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
void getSize(@NonNull SizeReadyCallback cb) {
//获取target的宽高
int currentWidth = getTargetWidth();
int currentHeight = getTargetHeight();
//如果宽高校验通过则回调到SingleRequest的onSizeReady
if (isViewStateAndSizeValid(currentWidth, currentHeight)) {
cb.onSizeReady(currentWidth, currentHeight);
return;
}
if (!cbs.contains(cb)) {
cbs.add(cb);
}
if (layoutListener == null) {
ViewTreeObserver observer = view.getViewTreeObserver();
layoutListener = new SizeDeterminerLayoutListener(this);
//否则监听绘制的前置事件
observer.addOnPreDrawListener(layoutListener);
}
}
|
获取target的宽高,如果宽高校验通过则回调到SingleRequest中,否则监听target的绘制前置事件。我们看下如何获取宽高的:
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 int getTargetWidth() {
int horizontalPadding = view.getPaddingLeft() + view.getPaddingRight();
LayoutParams layoutParams = view.getLayoutParams();
int layoutParamSize = layoutParams != null ? layoutParams.width : PENDING_SIZE;
return getTargetDimen(view.getWidth(), layoutParamSize, horizontalPadding);
}
private int getTargetDimen(int viewSize, int paramSize, int paddingSize) {
int adjustedParamSize = paramSize - paddingSize;
//如果layoutParams中设置了精确宽度
if (adjustedParamSize > 0) {
return adjustedParamSize;
}
//默认不走这里
if (waitForLayout && view.isLayoutRequested()) {
return PENDING_SIZE;
}
//默认viewSize等于0,也不走这里
int adjustedViewSize = viewSize - paddingSize;
if (adjustedViewSize > 0) {
return adjustedViewSize;
}
//如果imageView没有经过测量,并且宽度设置的是WRAP_CONTENT,走这里
if (!view.isLayoutRequested() && paramSize == LayoutParams.WRAP_CONTENT) {
return getMaxDisplayLength(view.getContext());
}
return PENDING_SIZE;
}
|
我们只分析宽度和高度为LayoutParams.WRAP_CONTENT情况,此时会调getMaxDisplayLength:
1
2
3
4
5
6
7
8
9
10
11
|
private static int getMaxDisplayLength(@NonNull Context context) {
if (maxDisplayLength == null) {
WindowManager windowManager =
(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = Preconditions.checkNotNull(windowManager).getDefaultDisplay();
Point displayDimensions = new Point();
display.getSize(displayDimensions);
maxDisplayLength = Math.max(displayDimensions.x, displayDimensions.y);
}
return maxDisplayLength;
}
|
可以看到获取的是屏幕的宽高,所以如果没有imageView定宽高,并且还没到测量的时候,此时设置的初始宽高是屏幕的宽高。获取到默认宽高后会回调到SingleRequest的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
|
public void onSizeReady(int width, int height) {
synchronized (requestLock) {
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;
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;
}
}
}
|
调用了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) {
//构建EngineKey,由于不需要外部去控制key,所以keyFactory是一个普通的factory,不需要进行扩展
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);
}
}
cb.onResourceReady(
memoryResource, DataSource.MEMORY_CACHE, /* isLoadedFromAlternateCacheKey= */ false);
return null;
}
|
先不用管内存加载这块,直接看waitForExistingOrStartNewJob方法:
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
|
private <R> LoadStatus waitForExistingOrStartNewJob(
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,
EngineKey key,
long startTime) {
//从已存在的job列表中找相同的EngineJob
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb, callbackExecutor);
return new LoadStatus(cb, current);
}
//如果没有找到相同的EngineJob,则构建一个新的出来
EngineJob<R> engineJob =
engineJobFactory.build(
key,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache);
//构建DecodeJob
DecodeJob<R> decodeJob =
decodeJobFactory.build(
glideContext,
model,
key,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
onlyRetrieveFromCache,
options,
engineJob);
//将构建好的EngineJob放到job列表中
jobs.put(key, engineJob);
//将cb添加到EngineJob中作为回调,这里的cb是前面的SingleRequest
engineJob.addCallback(cb, callbackExecutor);
//触发加载逻辑
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}
|
上面创建EngineJob和DecodeJob,从名字看EngineJob是专门用来加载主逻辑的Job,DecodeJob是解码用的。先不管它们是怎么创建的,后面会讲到,直接看EngineJob的start方法:
1
2
3
4
5
6
|
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
GlideExecutor executor =
decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
executor.execute(decodeJob);
}
|
此时将DecodeJob作为runnable放到线程池中执行,看下它的run方法:
1
2
3
|
public void run() {
runWrapped();
}
|
其余的代码删除掉了,只保留核心的方法调用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
stage = getNextStage(Stage.INITIALIZE);
currentGenerator = getNextGenerator();
runGenerators();
break;
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
case DECODE_DATA:
decodeFromRetrievedData();
break;
}
}
|
runReason的默认值是INITIALIZE,然后调用getNextStage获取到当前stage,然后通过getNextGenerator获取下一个generator,然后调用runGenerators来执行generator,来看下这一段逻辑:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
private Stage getNextStage(Stage current) {
switch (current) {
case INITIALIZE:
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:
return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
case SOURCE:
case FINISHED:
return Stage.FINISHED;
default:
throw new IllegalArgumentException("Unrecognized stage: " + current);
}
}
|
默认是支持decodeCachedResource的,它表示是否获取解码后的缓存资源,所以此时返回Stage.RESOURCE_CACHE,接着调用getNextGenerator方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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);
}
}
|
创建了ResourceCacheGenerator,然后调用runGenerators方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
private void runGenerators() {
boolean isStarted = false;
//调用当前的generator,如果它的startNext方法返回false,则继续获取下一个stage,并继续调用下一个generator的startNext方法
while (!isCancelled
&& currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
if (stage == Stage.SOURCE) {
reschedule(RunReason.SWITCH_TO_SOURCE_SERVICE);
return;
}
}
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
}
|
我们直接看stage为SOURCE,generator直接是SourceGenerator时候,看下它的startNext方法:
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 boolean startNext() {
//如果已经缓存上了,直接用缓存的数据
if (dataToCache != null) {
Object data = dataToCache;
dataToCache = null;
try {
boolean isDataInCache = cacheData(data);
if (!isDataInCache) {
return true;
}
} catch (IOException e) {
}
}
//如果sourceCacheGenerator中能拿到数据直接返回
if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
return true;
}
sourceCacheGenerator = null;
loadData = null;
boolean started = false;
//从DecodeHelper中获取loadData
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则调该方法
startNextLoad(loadData);
}
}
return started;
}
|
startNext中首先从DecodeHelper中获取到loadData,此处我们先不用管怎么获取到loadData,获取到loadData后调用startNextLoad方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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);
}
}
});
}
|
此时调用loadData中的fetcher的loadData方法,此处的loadData.fetcher是谁呢?这个后面的章节再了解,先知道是HttpUrlFetcher,然后看下它的loadData方法:
1
2
3
4
5
6
7
8
9
|
public void loadData(
@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
try {
InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
callback.onDataReady(result);
} catch (IOException e) {
callback.onLoadFailed(e);
}
}
|
调用了loadDataWithRedirects方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
private InputStream loadDataWithRedirects(
URL url, int redirects, URL lastUrl, Map<String, String> headers) throws HttpException {
urlConnection = buildAndConfigureConnection(url, headers);
try {
urlConnection.connect();
stream = urlConnection.getInputStream();
} catch (IOException e) {
throw new HttpException(
"Failed to connect or obtain data", getHttpStatusCodeOrInvalid(urlConnection), e);
}
if (isCancelled) {
return null;
}
final int statusCode = getHttpStatusCodeOrInvalid(urlConnection);
if (isHttpOk(statusCode)) {
return getStreamForSuccessfulRequest(urlConnection);
}
}
|
通过buildAndConfigureConnection创建了HttpURLConnection,接着通过code码解析对应的InputStream,结束后回调到SourceGenerator内部类DataCallback的onDataReady,然后回调到SourceGenerator的onDataReadyInternal:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
void onDataReadyInternal(LoadData<?> loadData, Object data) {
DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
dataToCache = data;
cb.reschedule();
} else {
cb.onDataFetcherReady(
loadData.sourceKey,
data,
loadData.fetcher,
loadData.fetcher.getDataSource(),
originalKey);
}
}
|
将获取到的数据给到dataToCache,并且回调到DecodeJob的reschedule方法:
1
2
3
4
5
6
7
8
|
public void reschedule() {
reschedule(RunReason.SWITCH_TO_SOURCE_SERVICE);
}
private void reschedule(RunReason runReason) {
this.runReason = runReason;
callback.reschedule(this);
}
|
此处的callback是EngineJob,继续回调到reschedule:
1
2
3
|
public void reschedule(DecodeJob<?> job) {
getActiveSourceExecutor().execute(job);
}
|
此处又是一个线程池,再次执行DecodeJob,注意了此时DecodeJob中的runReason是SWITCH_TO_SOURCE_SERVICE,又回到刚才说的runWrapped方法中:
1
2
3
4
5
6
7
|
private void runWrapped() {
switch (runReason) {
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
}
}
|