Glide源码解析

1
Glide.with(this).load("https://wod.jpg").into(ig)

Glide通过with方法创建了对象Glide , RequestManagerRetrier ,RequestManager

然后通过load方法创建对象RequestBuilder

   先来看下Glide对象是怎么创建的:

   进入with方法:

1
2
3
4
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
// 可以看到调用with实际是创建了对象 RequestManager

   看下getRetriever方法干了什么:

1
2
3
4
5
6
7
8
9
10
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
Preconditions.checkNotNull(
context,
"一段描述信息");
return Glide.get(context).getRequestManagerRetriever();
}
// 可以看到通过getRetriever方法创建了对象 RequestManagerRetriever
// 创建RequestManagerRetrier对象又是通过Glide对象创建的。
// Glide对象又是通过Glide.get(context)方法,懒加载的方式创建的单例对象。
// 在调用Glide.get(context)方法创建对象Glide在里面又创建了对象RequestManagerRetriever

   总结:当我们调用Glide.with方法的时候,在内部先调用了Glide.get(context),方式创建了Glide对象。然后通过调用Glide.get(context).getRequestManagerRetriever方法创建了RequestManagerRetrier对象。然后在是通过ReqeustManagerRetrier对象调用了get(context)获取对象RequestManager

   Glide对象的创建用了工厂模式:创建了对象GlideBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
private static void checkAndInitializeGlide(@NonNull Context context) {
initializeGlide(context);
}
private static void initializeGlide(@NonNull Context context) {
initializeGlide(context, new GlideBuilder());
}
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
// 通过工厂模式创建了Glide对象。
Glide glide = builder.build(applicationContext);

Glide.glide = glide;
}

   来看下工厂里面创建了那些对象GlideBuilder.build

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
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) {
// 获取手机内存大小。大的手机这个size一定是大于0的
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) {
// 这个创建的就是磁盘缓存,缓存的文件保存在 项目/cache/img_manager_disk_cache
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}

if (engine == null) {
engine =
new Engine(
memoryCache,
diskCacheFactory,//磁盘缓存
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
GlideExecutor.newAnimationExecutor(),
isActiveResourceRetentionAllowed);
}

if (defaultRequestListeners == null) {
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}

RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);

return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptions.lock(),
defaultTransitionOptions,
defaultRequestListeners,
isLoggingRequestOriginsEnabled);
}
// 可以看到创建了对象:三个都是线程池
// 这三个都继承自Executor接口。可想而知他们是和线程池有关系。
/**
* GlideExecutor sourceExecutor;// 源执行人
* GlideExecutor diskCacheExecutor;//磁盘高速缓存执行人
* GlideExecutor animationExecutor;// 动画线程池
* MemorySizeCalculator memorySizeCalculator; //内存大小的计算器
* DefaultConnectivityMonitorFactory connectivityMonitorFactory;//默认连接监视器工厂
* BitmaoPool bitmapPool;//如果内存大小计算器大于0 则bitmapPool = LruBitmapPool
* // 否则等于 BitmapPoolAdapter
* ArrayPool arrayPool;// 创建对象LruArrayPool
* MemoryCache memoryCache;// 创建对象LruResourceCache
* DiskCache.Factory diskCacheFactory;// 创建对象InternalCacheDiskCacheFactory 这是我们的磁盘缓存,也就是把下载的图片保存在本地项目/cache/image_manager_disk_cache文件里面
* Engine engine;//创建对象Engine
* RequestManagerRetriever requestManagerRetriever;//创建对象RequestManagerRetriever
*/
// 自此Glide对象创建完毕。

这里面我们看到了一个bitmapPool对象,它是个啥呢。怎么还通过了一个size去判断创建什么对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BitmapPool bitmapPool;
MemorySizeCalculator memorySizeCalculator;
if (memorySizeCalculator == null) {
memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
}
if (bitmapPool == null) {
int size = memorySizeCalculator.getBitmapPoolSize();
if (size > 0) {
//LruBitmapPool这也是一个缓存,不过我还不知道是在什么时候会调用它的put方法将图片塞到他的队列里面
//不过现在知道在put的时候会获取这个bitmap的大小是否大于size如果大于的话就不缓存,防止内存爆
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}

这个MemorySizeCalculator从名字就可以知道是内存大小计算器。内存指的是手机的ram大小,ram是随机存储寄存器。我们看下他是怎么获取咱们手机的内存大小的:

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
//MemorySizeCalculator.Builder(context):
//可以看到先通过Builder方法获取到了我们的 ActivityManager对象。
//然后调用我们系统方法 ActivityManager.isLowRamDevice方法判断是不是低内存的手机
public Builder(Context context) {
this.context = context;
activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
screenDimensions =
new DisplayMetricsScreenDimensions(context.getResources().getDisplayMetrics());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isLowMemoryDevice(activityManager)) {
bitmapPoolScreens = 0;
}
}
static boolean isLowMemoryDevice(ActivityManager activityManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return activityManager.isLowRamDevice();
} else {
return true;
}
}
public MemorySizeCalculator build() {
return new MemorySizeCalculator(this);
}
// 在它的构造函数里面我们可以看到对内存进行了计算
MemorySizeCalculator(MemorySizeCalculator.Builder builder) {
this.context = builder.context;

arrayPoolSize =
isLowMemoryDevice(builder.activityManager)
? builder.arrayPoolSizeBytes / LOW_MEMORY_BYTE_ARRAY_POOL_DIVISOR
: builder.arrayPoolSizeBytes;
int maxSize =
getMaxSize(
builder.activityManager, builder.maxSizeMultiplier, builder.lowMemoryMaxSizeMultiplier);

int widthPixels = builder.screenDimensions.getWidthPixels();
int heightPixels = builder.screenDimensions.getHeightPixels();
int screenSize = widthPixels * heightPixels * BYTES_PER_ARGB_8888_PIXEL;

int targetBitmapPoolSize = Math.round(screenSize * builder.bitmapPoolScreens);

int targetMemoryCacheSize = Math.round(screenSize * builder.memoryCacheScreens);
int availableSize = maxSize - arrayPoolSize;

if (targetMemoryCacheSize + targetBitmapPoolSize <= availableSize) {
memoryCacheSize = targetMemoryCacheSize;
bitmapPoolSize = targetBitmapPoolSize;
} else {
float part = availableSize / (builder.bitmapPoolScreens + builder.memoryCacheScreens);
memoryCacheSize = Math.round(part * builder.memoryCacheScreens);
bitmapPoolSize = Math.round(part * builder.bitmapPoolScreens);
}
}

Glide里面使用到的线程池

在创建Glide对象的时候有一个参数叫Engine

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
Glide build(@NonNull Context context) {
if (engine == null) {
engine =
new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
experiments);
}

   看下Engine这个类的构造函数:

1
2
3
4
5
6
7
8
9
10
public Engine(
MemoryCache memoryCache,
DiskCache.Factory diskCacheFactory,
GlideExecutor diskCacheExecutor,
GlideExecutor sourceExecutor,
GlideExecutor sourceUnlimitedExecutor,
GlideExecutor animationExecutor,
boolean isActiveResourceRetentionAllowed) {
//isActiveResourceRetentionAllowed 是否允许保留活动资源
}

   可以看Engine里面保存了我们会使用到的所有线程池(总共四个)。分别是:

  • diskCacheExecutor
  • sourceExecutor
  • sourceUnlimitedExecutor
  • animationExecutor

我们可以看下这四个线程池是什么时候创建的:

   这四个线程池都是在GlideBuilder.build方法里面创建的:

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
// GlideBuilder
Glide build(@NonNull Context context) {
if (sourceExecutor == null) {
sourceExecutor = GlideExecutor.newSourceExecutor();
}

if (diskCacheExecutor == null) {
diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
}

if (animationExecutor == null) {
animationExecutor = GlideExecutor.newAnimationExecutor();
}

if (engine == null) {
engine =
new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
}

   可以看到diskCacheExecutor , sourceExecutor ,animationExecutor 的线程池的队列用的都是PriorityBlockingQueue。也就代表这个线程池永远不会满。也就不会触发RejectedExecutionException这个报错。这里唯一特殊的是sourceUnlimitedExecutor他的创建是GlideExecutor.newUnlimitedSourceExecutor()

1
2
3
4
5
6
7
8
9
10
11
public static GlideExecutor newUnlimitedSourceExecutor() {
return new GlideExecutor(
new ThreadPoolExecutor(
0,
Integer.MAX_VALUE,
KEEP_ALIVE_TIME_MS,
TimeUnit.MILLISECONDS,
new SynchronousQueue<Runnable>(),
new DefaultThreadFactory(
DEFAULT_SOURCE_UNLIMITED_EXECUTOR_NAME, UncaughtThrowableStrategy.DEFAULT, false)));
}

   可以看到它的缓存队列是SynchronousQueue,这个队列是有界的,所以当我们触发大量网络请求得时候,很可能会触发RejectedExecutionException这个报错。

   在回过头来看下public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
这个get(activity)干了什么:

进入类RequestManagerRetriver:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 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 Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
// 我们可以通过RequestManager这个类名就能猜到是一个请求管理类。他管理了请求的生命周期。
// 通过我们的context去创建对应的生命周期管理类。

   看完Glide.with(context)方法可以看出,我们app的全局Glide对象是唯一的,它的创建用的是单例模式。所以可以这么说Glide对象里面创建过的所有对象也都只有一份,不会重复创建。唯一的是每次调用Glide.with方法都会重新创建RequestManager对象。


   with方法看完了,现在来看下load方法:

1
2
3
4
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
// 他创建了对象RequestBuilder<T>

   看下asDrawable

1
2
3
4
5
6
7
8
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
// 可以看到这个resourceClass就是 Drawable.class
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}

可以看到通过asDrawable方法创建了对象RequestBuilder

  看下into方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
switch (view.getScaleType()) {
case FIT_XY:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
default:
}
return into(
// 返回的是ViewTarget<ImageView,X>
glideContext.buildImageViewTarget(view, transcodeClass),
null,
requestOptions,// 这个是图片展示模式什么得
Executors.mainThreadExecutor());
}

   看下glideContext.buildImageViewTarget(view, transcodeClass)方法是怎么创建ViewTarget对象的:

首先需要知道这个glideContext:GlideContext对象是什么,这个GlideContext对象是在RequestBuilder的构造函数里面进行赋值的,获取的是Glide构造函数里面创建的GlideContext对象:

1
2
3
4
5
6
7
8
9
protected RequestBuilder(
@NonNull Glide glide,
RequestManager requestManager,
Class<TranscodeType> transcodeClass,
Context context) {
this.glide = glide;
this.glideContext = glide.getGlideContext();
this.transcodeClass = transcodeClass;
}

   在看buildImageViewTarget方法前还需要知道这个transcodeClass是什么?可以知道这个对象也是在RequestBuilder的构造函数里面传递的。见上面的构造函数。现在回到RequestBuilder创建的地方:可以看上面讲了RequestBuilder的创建过程。看完上面的讲解,知道了这个transcodeClass就是Drawable.class

  现在在回到主线glideContext.buildImageViewTarger方法:

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);
} else {
}
}

通过上面我们知道了我们传进来的transcodeClassDrawable.class。所以可以知道最终创建出来的ViewTarget是BitmapImageViewTarget对象。

   分析完ViewTarget的创建过程,现在继续回到主线RequestBuilder.into方法

   接着看into方法:into方法完成了请求的创建Request然后将请求发送出去Request.begin

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
// RequestBuilder
// 这里知道了target是BitmapImageViewTarget
// targetListener=null
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)) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
return target;
}
// 这里创建了请求类Request,然后还判断了之前有没有发送过,如果发送了就不在进行新的请求。

   看下Request的创建过程:可以看到先调用buildRequest方法,然后内部调用了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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Request request = buildRequest(target, targetListener, options, callbackExecutor);
private Request buildRequest(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
//构建请求递归
return buildRequestRecursive(
target,
targetListener,
null,
transitionOptions,
requestOptions.getPriority(),
requestOptions.getOverrideWidth(),
requestOptions.getOverrideHeight(),
requestOptions,
callbackExecutor);
}
//构建请求递归
private Request buildRequestRecursive(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
//这个errorBuilder是我们通过RequetBuilder调用error方法传入了RequestBuilder对象。这是在我们请求失败图后才会走这个error的请求。
ErrorRequestCoordinator errorRequestCoordinator = null;
if (errorBuilder != null) {
// 可以看到如果用户设置了创建失败的errorBuilder那么就会去创建一个错误拦截器:ErrorRequestCoordinator对象。
errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}

Request mainRequest =
//构建缩略图请求递归
buildThumbnailRequestRecursive(
target,
targetListener,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
requestOptions,
callbackExecutor);
// 如果没有失败拦截器就直接返回mainRequest
if (errorRequestCoordinator == null) {
return mainRequest;
}

int errorOverrideWidth = errorBuilder.getOverrideWidth();
int errorOverrideHeight = errorBuilder.getOverrideHeight();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !errorBuilder.isValidOverride()) {
errorOverrideWidth = requestOptions.getOverrideWidth();
errorOverrideHeight = requestOptions.getOverrideHeight();
}

Request errorRequest =
//构建请求递归
errorBuilder.buildRequestRecursive(
target,
targetListener,
errorRequestCoordinator,
errorBuilder.transitionOptions,
errorBuilder.getPriority(),
errorOverrideWidth,
errorOverrideHeight,
errorBuilder,
callbackExecutor);
errorRequestCoordinator.setRequests(mainRequest, errorRequest);
return errorRequestCoordinator;
}

   在构建Request对象的时候,当我们没有设置error情况的时候就直接去创建mainRqeust,这里为了尽快分析完整个请求过程我就只分析了mainRequest的创建过程

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
121
122
123
124
// 创建mainRequest方法调用的方法
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) {
// 这个是缩略图的展示。我们如果没有调用 Glide.with(context).load("http://..").thumbnail()
// 方法来创建缩略图的话,那么这个thumbnailBuilder的值就是null。
// 这里默认没调用thumbnail方法。
if (thumbnailBuilder != null) {
// 所以这里不会进来
if (isThumbnailBuilt) {
throw new IllegalStateException(
"报错。。。。。");
}

TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
thumbnailBuilder.transitionOptions;

// Apply our transition by default to thumbnail requests but avoid overriding custom options
// that may have been applied on the thumbnail request explicitly.
if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
thumbTransitionOptions = transitionOptions;
}

Priority thumbPriority =
thumbnailBuilder.isPrioritySet()
? thumbnailBuilder.getPriority()
: getThumbnailPriority(priority);

int thumbOverrideWidth = thumbnailBuilder.getOverrideWidth();
int thumbOverrideHeight = thumbnailBuilder.getOverrideHeight();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !thumbnailBuilder.isValidOverride()) {
thumbOverrideWidth = requestOptions.getOverrideWidth();
thumbOverrideHeight = requestOptions.getOverrideHeight();
}

ThumbnailRequestCoordinator coordinator =
new ThumbnailRequestCoordinator(requestLock, parentCoordinator);
Request fullRequest =
obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
coordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
isThumbnailBuilt = true;
// Recursively generate thumbnail requests.
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) {
// 这也同理没调用thumbnail这个方法这个值就不会动态设值进来
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 {
// 没有缩略图的情况下 Glide默认会进来的地方。
return obtainRequest(
requestLock,
target,
targetListener,
requestOptions,
parentCoordinator,
transitionOptions,
priority,
overrideWidth,
overrideHeight,
callbackExecutor);
}
}

   进入obtainRequest方法,这是没有创建缩略图的时候,默认创建Request的地方。可以看到在没有配置缩略图的时候,默认的RequestSingleRequest

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

   至此Request就创建完毕了。

   既然已经知道Request对象是SingleRequest了。那就直接进入SingleRequestbegin方法。

1
2
3
4
5
6
7
8
public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
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
// SingleRequest
public synchronized void begin() {
assertNotCallingCallbacks();
stateVerifier.throwIfRecycled();
startTime = LogTime.getLogTime();
// 这个model就是我们调用Glide.whit().load("http:...")
// load里面的String.class 可以看上面我贴出来了model对象的赋值过程。
if (model == null) {
return;
}

if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}

if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
//对于既不完整也不运行的请求重新启动可以被视为新请求,并可以重新开始运行。
status = Status.WAITING_FOR_SIZE;
//isValidDimensions 是否是有效的。
// 当宽高不是有效值 默认的值为-1 所以第一次进行请求的时候会进入onSizeReady方法。
// 看过onSizeReady源码你就会知道,他会回调到ViewTarget里面去获取我们ImageView的宽高,获取完毕的后,又会通过回调的方式调用SingleRequest里面的onSizeReady方法。在onSizeReady方法里面回去执行engine.load方法正正开启往了请求。
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
// 如果知道了大小数据则直接进行网络请求 调用了engind.load方法。
onSizeReady(overrideWidth, overrideHeight);
} else {
// 这个target就是我们求前面讲的在调用into方法的时候去创建了一个ViewTarget对象。然后也分析了这个ViewTarget对象就是BitmaoImageViewTarget
// 去获取大小,大小获取完回回调出来 调用了onSizeReady方法。onSizeReady里面调用了正正的网络请求 engine.load方法。
target.getSize(this);
}

// 这个就是回调到viewTarget告诉使用者,这次的网络求准备就绪。马上开始调用engine.load方法去获取数据,。
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
}

   看下onSizeReady,它就意味着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
// SingleRequest
public synchronized void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled(){
// 判断状态已经在请求得话不重复进行
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;

float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
// engine是在创建Glide对象的时候创建好的。glide是要给单例,整个程序就只会创建一次。engine也一样。
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;
}
if (IS_VERBOSE_LOGGABLE) {
logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
}

   开始真正得网络请求:load

  • 开始加载给定参数。
    必须在主线程上调用。
    任何请求的流程如下:
    检查当前使用的资源集,返回活动资源(如果存在),并将任何新的非活动资源移动到内存缓存中。
    检查内存缓存并提供缓存资源(如果存在)。
    检查当前的一组正在进行的加载并将 cb 添加到进行中的加载(如果存在)。
    开始新的加载。
    活动资源是那些已提供给至少一个请求但尚未释放的资源。 一旦资源的所有消费者都释放了该资源,该资源就会进入缓存。 如果资源从缓存中返回给新的使用者,它会重新添加到活动资源中。 如果资源从缓存中被逐出,它的资源将被回收并在可能的情况下重新使用,并丢弃该资源。 没有严格要求消费者释放他们的资源,因此活跃的资源被弱持有。

参数:

  • width – 所需资源的目标宽度(以像素为单位)。
    height – 所需资源的目标高度(以像素为单位)。
    cb – 加载完成时将调用的回调
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
public synchronized <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<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}

EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}

EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb, callbackExecutor);
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current);
}

EngineJob<R> engineJob =
engineJobFactory.build(
key,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache);

DecodeJob<R> decodeJob =
decodeJobFactory.build(
glideContext,
model,
key,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
onlyRetrieveFromCache,
options,
engineJob);
jobs.put(key, engineJob);
engineJob.addCallback(cb, callbackExecutor);
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}

   首先从缓存里面进行查找,如果缓存没有的话就创建新的网络请求。

   在使用Glide得时候,我们可以使用Glide.with(this).load(mUrl).skipMemoryCache(false)方法设置需不需要走缓存。设置为false就是不走缓存,那么每次都是重新请求。默认是true。走缓存。

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
private EngineResource<?> loadFromMemory(
EngineKey key, boolean isMemoryCacheable, long startTime) {
// 为false得时候也就不会走缓存查找了
if (!isMemoryCacheable) {
return null;
}
// 这是活动缓存 通过弱引用的方式保存数据 实现类是ActiveResources
EngineResource<?> active = loadFromActiveResources(key);
if (active != null) {
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return active;
}
//从LruCache获取缓存图片 实现类 LruResourceCache
EngineResource<?> cached = loadFromCache(key);
if (cached != null) {
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return cached;
}

return null;
}

   先从活动缓存里面找(活动缓存ActiveCache:正在使用的图片),不使用了后就从活动缓存里面删掉,删掉的数据放到MemoryCache

   内存缓存:回收机制:LRU最少使用算法来管理的。被使用的时候会将数据提到磁盘缓存。如果最少使用,内部算法会回收。活动缓存被回收的数据又会被丢回到内存缓存

   你正在使用的图片—-[活动缓存]。如果不用了,才会扫描回收。[存入 移除 非常快]。

   在Glide里面内存缓存的类是LruResourceCache

缓存策略

组合策略

和其他三级缓存一样,Glide的缓存读取顺序是 内存->磁盘->网络

需要注意的是Glide的内存缓存和磁盘缓存的配置是相互没有直接影响,所以可以同时进行配置:

例:

  1. 内存不缓存,磁盘缓存所有图片

    1
    Glide.with(this).load(url).skipMemoryCache(true).disCacheStratrgy(DiskCachestrat.ALL).into(imageview)
  2. 内存缓存处理图,磁盘缓存原图

    1
    Glide.with(this).load(mUrl).skipMemoryCache(false).diskCacheStrategy(DiskCacheStrategy.SOURCE).into(mIv);

缓存大小及路径

2.1 内存缓存最大空间

Glide的内存缓存其实涉及到表较多的计算,这里就介绍最重要的一个参数。就是内存缓存最大空间内存缓存最大空间(maxSize)=每个进程可用的最大内存0.4。(低配手机的话就是:每个进程可用的最大内存0.33)

2.2 磁盘缓存大小

磁盘缓存大小:250*1024*1024(250MB)

1
2
/**250MB of cache**/
int DEFULT_DISK_CACHE_SIZE = 250*1024*1024

2.3 磁盘缓存目录

磁盘缓存目录:项目/cache/image_manager_disk_cache

1
String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";

清理缓存

3.1 清理所有缓存

清理所有内存缓存(需要在ui线程操作)

1
Glide.get(this).clearMemory();

清理所有磁盘缓存(需要在子线程操作)

1
Glide.get(MainActivity.this).clearDiskCache();

注:在使用中的资源不会被清除。