0
# Glide Caching Strategies System
1
2
Glide's sophisticated caching system provides multi-level caching with both memory and disk components, offering fine-grained control over cache behavior, sizing, and strategies. The system is built around the `MemoryCache` and `DiskCache` interfaces with configurable strategies through the `DiskCacheStrategy` enum and comprehensive cache management APIs.
3
4
## MemoryCache Interface
5
6
The memory cache provides fast access to recently loaded images, keeping them in RAM for immediate display:
7
8
```java { .api }
9
public interface MemoryCache {
10
/**
11
* Gets the current size of the cache in bytes
12
* @return Current cache size
13
*/
14
long getCurrentSize();
15
16
/**
17
* Gets the maximum size of the cache in bytes
18
* @return Maximum cache size
19
*/
20
long getMaxSize();
21
22
/**
23
* Sets a multiplier for the cache size
24
* @param multiplier Size multiplier (0.0-1.0)
25
*/
26
void setSizeMultiplier(float multiplier);
27
28
/**
29
* Stores a resource in the cache
30
* @param key The cache key
31
* @param resource The resource to cache
32
* @return Previous resource at key, or null
33
*/
34
Resource<?> put(Key key, Resource<?> resource);
35
36
/**
37
* Retrieves a resource from the cache
38
* @param key The cache key
39
* @return Cached resource or null
40
*/
41
Resource<?> remove(Key key);
42
43
/**
44
* Clears all entries from memory cache
45
*/
46
void clearMemory();
47
48
/**
49
* Trims memory cache to specified level
50
* @param level Trim level from ComponentCallbacks2
51
*/
52
void trimMemory(int level);
53
}
54
```
55
56
## DiskCache Interface
57
58
The disk cache provides persistent storage for images across application restarts:
59
60
```java { .api }
61
public interface DiskCache {
62
63
/**
64
* Writer interface for writing cache entries
65
*/
66
public interface Writer {
67
/**
68
* Writes data to the cache entry
69
* @param file The file to write to
70
* @return True if write successful
71
*/
72
boolean write(File file);
73
}
74
75
/**
76
* Factory interface for creating disk caches
77
*/
78
public interface Factory {
79
/**
80
* Default disk cache directory name
81
*/
82
String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
83
84
/**
85
* Default disk cache size in bytes (250 MB)
86
*/
87
long DEFAULT_DISK_CACHE_SIZE = 250L * 1024 * 1024;
88
89
/**
90
* Creates a disk cache instance
91
* @return New DiskCache instance
92
*/
93
DiskCache build();
94
}
95
96
/**
97
* Retrieves a file from the cache
98
* @param key The cache key
99
* @return Cached file or null
100
*/
101
File get(Key key);
102
103
/**
104
* Stores data in the cache
105
* @param key The cache key
106
* @param writer Writer to create cache entry
107
*/
108
void put(Key key, Writer writer);
109
110
/**
111
* Removes entry from cache
112
* @param key The cache key
113
*/
114
void delete(Key key);
115
116
/**
117
* Clears all entries from disk cache
118
*/
119
void clear();
120
}
121
```
122
123
## DiskCacheStrategy Enum
124
125
Controls which versions of images are cached to disk:
126
127
```java { .api }
128
public enum DiskCacheStrategy {
129
/**
130
* Caches all versions of images (original and transformed)
131
* Provides fastest loading but uses most disk space
132
*/
133
ALL,
134
135
/**
136
* Disables disk caching completely
137
* Saves disk space but requires re-downloading/processing
138
*/
139
NONE,
140
141
/**
142
* Caches only original source data
143
* Useful for images that are transformed differently
144
*/
145
DATA,
146
147
/**
148
* Caches only transformed/processed images
149
* Good for consistent transformations
150
*/
151
RESOURCE,
152
153
/**
154
* Intelligently chooses strategy based on image source
155
* Default strategy - caches remote images but not local
156
*/
157
AUTOMATIC;
158
159
/**
160
* Gets default strategy
161
*/
162
public static DiskCacheStrategy getDefault() {
163
return AUTOMATIC;
164
}
165
166
/**
167
* Checks if strategy caches original data
168
*/
169
public static boolean isDataCacheable(DiskCacheStrategy strategy) {
170
return strategy == ALL || strategy == DATA || strategy == AUTOMATIC;
171
}
172
173
/**
174
* Checks if strategy caches processed resources
175
*/
176
public static boolean isResourceCacheable(DiskCacheStrategy strategy) {
177
return strategy == ALL || strategy == RESOURCE || strategy == AUTOMATIC;
178
}
179
}
180
```
181
182
## LruResourceCache Implementation
183
184
The default memory cache implementation using Least Recently Used (LRU) eviction:
185
186
```java { .api }
187
public class LruResourceCache implements MemoryCache {
188
private final long maxSize;
189
190
/**
191
* Creates LRU cache with specified size
192
* @param maxSize Maximum cache size in bytes
193
*/
194
public LruResourceCache(long maxSize) {
195
this.maxSize = maxSize;
196
}
197
198
@Override
199
public long getCurrentSize() {
200
// Implementation details
201
return 0;
202
}
203
204
@Override
205
public long getMaxSize() {
206
return maxSize;
207
}
208
209
@Override
210
public void setSizeMultiplier(float multiplier) {
211
// Implementation details
212
}
213
214
@Override
215
public Resource<?> put(Key key, Resource<?> resource) {
216
// Implementation details
217
return null;
218
}
219
220
@Override
221
public Resource<?> remove(Key key) {
222
// Implementation details
223
return null;
224
}
225
226
@Override
227
public void clearMemory() {
228
// Implementation details
229
}
230
231
@Override
232
public void trimMemory(int level) {
233
// Implementation details
234
}
235
236
/**
237
* Gets current number of entries
238
*/
239
public int getCurrentEntryCount() {
240
// Implementation details
241
return 0;
242
}
243
244
/**
245
* Gets eviction count since creation
246
*/
247
public long getEvictionCount() {
248
// Implementation details
249
return 0;
250
}
251
}
252
```
253
254
## Disk Cache Factories
255
256
### InternalCacheDiskCacheFactory
257
258
Creates disk cache in internal app storage:
259
260
```java { .api }
261
public class InternalCacheDiskCacheFactory implements DiskCache.Factory {
262
private final Context context;
263
private final String diskCacheName;
264
private final long diskCacheSize;
265
266
/**
267
* Creates internal cache factory with default settings
268
* @param context Application context
269
*/
270
public InternalCacheDiskCacheFactory(Context context) {
271
this(context, DEFAULT_DISK_CACHE_DIR, DEFAULT_DISK_CACHE_SIZE);
272
}
273
274
/**
275
* Creates internal cache factory with custom size
276
* @param context Application context
277
* @param diskCacheSize Cache size in bytes
278
*/
279
public InternalCacheDiskCacheFactory(Context context, long diskCacheSize) {
280
this(context, DEFAULT_DISK_CACHE_DIR, diskCacheSize);
281
}
282
283
/**
284
* Creates internal cache factory with all custom parameters
285
* @param context Application context
286
* @param diskCacheName Cache directory name
287
* @param diskCacheSize Cache size in bytes
288
*/
289
public InternalCacheDiskCacheFactory(Context context, String diskCacheName, long diskCacheSize) {
290
this.context = context;
291
this.diskCacheName = diskCacheName;
292
this.diskCacheSize = diskCacheSize;
293
}
294
295
@Override
296
public DiskCache build() {
297
// Implementation details
298
return null;
299
}
300
}
301
```
302
303
### ExternalCacheDiskCacheFactory
304
305
Creates disk cache in external storage (SD card):
306
307
```java { .api }
308
public class ExternalCacheDiskCacheFactory implements DiskCache.Factory {
309
private final Context context;
310
private final String diskCacheName;
311
private final long diskCacheSize;
312
313
/**
314
* Creates external cache factory with default settings
315
* @param context Application context
316
*/
317
public ExternalCacheDiskCacheFactory(Context context) {
318
this(context, DEFAULT_DISK_CACHE_DIR, DEFAULT_DISK_CACHE_SIZE);
319
}
320
321
/**
322
* Creates external cache factory with custom directory
323
* @param context Application context
324
* @param diskCacheFolder Custom cache directory name
325
* @param diskCacheSize Cache size in bytes
326
*/
327
public ExternalCacheDiskCacheFactory(Context context, String diskCacheFolder, long diskCacheSize) {
328
this.context = context;
329
this.diskCacheName = diskCacheFolder;
330
this.diskCacheSize = diskCacheSize;
331
}
332
333
/**
334
* Creates external cache factory with all custom parameters
335
* @param context Application context
336
* @param diskCacheName Cache directory name
337
* @param diskCacheSize Cache size in bytes
338
*/
339
public ExternalCacheDiskCacheFactory(Context context, String diskCacheName, long diskCacheSize) {
340
this.context = context;
341
this.diskCacheName = diskCacheName;
342
this.diskCacheSize = diskCacheSize;
343
}
344
345
@Override
346
public DiskCache build() {
347
// Implementation details
348
return null;
349
}
350
}
351
```
352
353
## Cache Configuration
354
355
### Memory Cache Configuration
356
357
Configure memory cache size and behavior:
358
359
```java
360
public class CacheConfigurationActivity extends AppCompatActivity {
361
362
public void configureMemoryCache() {
363
// Get available memory
364
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
365
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
366
activityManager.getMemoryInfo(memoryInfo);
367
368
// Use 1/8th of available memory for image cache
369
long memoryCacheSize = memoryInfo.availMem / 8;
370
371
// Configure through GlideModule
372
class CustomGlideModule extends AppGlideModule {
373
@Override
374
public void applyOptions(Context context, GlideBuilder builder) {
375
builder.setMemoryCache(new LruResourceCache(memoryCacheSize));
376
}
377
}
378
}
379
380
public void runtimeMemoryCacheControl() {
381
// Clear memory cache
382
Glide.get(this).clearMemory();
383
384
// Trim memory cache based on system state
385
Glide.get(this).trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
386
387
// Get memory cache size info
388
MemoryCache memoryCache = Glide.get(this).getMemoryCache();
389
long currentSize = memoryCache.getCurrentSize();
390
long maxSize = memoryCache.getMaxSize();
391
392
Log.d("Cache", "Memory cache: " + currentSize + " / " + maxSize + " bytes");
393
}
394
}
395
```
396
397
### Disk Cache Configuration
398
399
Configure disk cache location and size:
400
401
```java
402
public class DiskCacheConfigurationActivity extends AppCompatActivity {
403
404
public void configureDiskCache() {
405
class CustomGlideModule extends AppGlideModule {
406
@Override
407
public void applyOptions(Context context, GlideBuilder builder) {
408
// Internal storage cache (100MB)
409
long internalCacheSize = 100 * 1024 * 1024L;
410
builder.setDiskCache(
411
new InternalCacheDiskCacheFactory(context, internalCacheSize)
412
);
413
414
// Or external storage cache (500MB)
415
long externalCacheSize = 500 * 1024 * 1024L;
416
builder.setDiskCache(
417
new ExternalCacheDiskCacheFactory(
418
context,
419
"my_app_cache",
420
externalCacheSize
421
)
422
);
423
}
424
}
425
}
426
427
public void clearDiskCache() {
428
// Must be called on background thread
429
new Thread(new Runnable() {
430
@Override
431
public void run() {
432
Glide.get(DiskCacheConfigurationActivity.this).clearDiskCache();
433
}
434
}).start();
435
}
436
}
437
```
438
439
## Cache Strategies Usage
440
441
### Per-Request Cache Control
442
443
Control caching behavior for individual requests:
444
445
```java
446
public class RequestCacheControlActivity extends AppCompatActivity {
447
448
public void demonstrateCacheStrategies() {
449
// Cache everything (original + transformed)
450
Glide.with(this)
451
.load(imageUrl)
452
.diskCacheStrategy(DiskCacheStrategy.ALL)
453
.into(imageView);
454
455
// Cache nothing to disk
456
Glide.with(this)
457
.load(imageUrl)
458
.diskCacheStrategy(DiskCacheStrategy.NONE)
459
.into(imageView);
460
461
// Cache only original data
462
Glide.with(this)
463
.load(imageUrl)
464
.diskCacheStrategy(DiskCacheStrategy.DATA)
465
.into(imageView);
466
467
// Cache only transformed result
468
Glide.with(this)
469
.load(imageUrl)
470
.transform(new CenterCrop())
471
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
472
.into(imageView);
473
474
// Skip memory cache but use disk cache
475
Glide.with(this)
476
.load(imageUrl)
477
.skipMemoryCache(true)
478
.diskCacheStrategy(DiskCacheStrategy.ALL)
479
.into(imageView);
480
}
481
482
public void cacheOnlyMode() {
483
// Load only from cache, don't fetch if not cached
484
Glide.with(this)
485
.load(imageUrl)
486
.onlyRetrieveFromCache(true)
487
.into(imageView);
488
}
489
}
490
```
491
492
### RequestOptions with Cache Settings
493
494
Create reusable cache configurations:
495
496
```java
497
public class CachePresets {
498
499
// High performance: cache everything
500
public static final RequestOptions PERFORMANCE_FOCUSED = new RequestOptions()
501
.diskCacheStrategy(DiskCacheStrategy.ALL)
502
.skipMemoryCache(false);
503
504
// Memory conscious: disk only
505
public static final RequestOptions MEMORY_CONSERVATIVE = new RequestOptions()
506
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
507
.skipMemoryCache(true);
508
509
// Bandwidth conscious: cache aggressively
510
public static final RequestOptions BANDWIDTH_CONSERVATIVE = new RequestOptions()
511
.diskCacheStrategy(DiskCacheStrategy.ALL)
512
.onlyRetrieveFromCache(false);
513
514
// Testing/debugging: no caching
515
public static final RequestOptions NO_CACHE = new RequestOptions()
516
.diskCacheStrategy(DiskCacheStrategy.NONE)
517
.skipMemoryCache(true);
518
}
519
520
public class CachePresetsActivity extends AppCompatActivity {
521
522
public void usePresets() {
523
// Apply performance preset
524
Glide.with(this)
525
.load(imageUrl)
526
.apply(CachePresets.PERFORMANCE_FOCUSED)
527
.into(imageView);
528
529
// Apply memory conservative preset
530
Glide.with(this)
531
.load(largeImageUrl)
532
.apply(CachePresets.MEMORY_CONSERVATIVE)
533
.into(imageView);
534
}
535
}
536
```
537
538
## Cache Key Generation
539
540
### Custom Cache Keys
541
542
Control cache behavior with custom cache keys:
543
544
```java
545
public class CacheKeyManagementActivity extends AppCompatActivity {
546
547
public void customCacheKeys() {
548
// Object-based cache key
549
ObjectKey objectKey = new ObjectKey("user_profile_123");
550
551
Glide.with(this)
552
.load(profileImageUrl)
553
.signature(objectKey)
554
.into(profileImageView);
555
556
// MediaStore signature for local files
557
MediaStoreSignature mediaStoreSignature = new MediaStoreSignature(
558
"image/jpeg",
559
lastModified,
560
ExifInterface.ORIENTATION_NORMAL
561
);
562
563
Glide.with(this)
564
.load(localImageFile)
565
.signature(mediaStoreSignature)
566
.into(imageView);
567
568
// Application version signature
569
ApplicationVersionSignature appVersionSignature = ApplicationVersionSignature.obtain(this);
570
571
Glide.with(this)
572
.load(imageUrl)
573
.signature(appVersionSignature)
574
.into(imageView);
575
}
576
577
public void combinedSignatures() {
578
// Combine multiple signatures
579
List<Object> keyComponents = Arrays.asList(
580
"user_id_123",
581
"profile_version_5",
582
System.currentTimeMillis() / (1000 * 60 * 60) // Hour-based cache
583
);
584
ObjectKey combinedKey = new ObjectKey(keyComponents);
585
586
Glide.with(this)
587
.load(profileUrl)
588
.signature(combinedKey)
589
.into(profileView);
590
}
591
}
592
```
593
594
## Advanced Cache Management
595
596
### Cache Size Monitoring
597
598
Monitor and adjust cache sizes dynamically:
599
600
```java
601
public class CacheMonitoringActivity extends AppCompatActivity {
602
603
public void monitorCacheUsage() {
604
MemoryCache memoryCache = Glide.get(this).getMemoryCache();
605
606
// Get current statistics
607
long currentSize = memoryCache.getCurrentSize();
608
long maxSize = memoryCache.getMaxSize();
609
int usagePercentage = (int) ((float) currentSize / maxSize * 100);
610
611
Log.d("CacheStats", "Memory cache usage: " + usagePercentage + "% (" + currentSize + " / " + maxSize + " bytes)");
612
613
// Adjust cache size based on memory pressure
614
if (usagePercentage > 90) {
615
memoryCache.setSizeMultiplier(0.8f); // Reduce by 20%
616
} else if (usagePercentage < 50) {
617
memoryCache.setSizeMultiplier(1.0f); // Full size
618
}
619
}
620
621
public void adaptiveCacheManagement() {
622
// Listen for memory pressure events
623
registerComponentCallbacks(new ComponentCallbacks2() {
624
@Override
625
public void onConfigurationChanged(Configuration newConfig) {}
626
627
@Override
628
public void onLowMemory() {
629
// Clear memory cache on low memory
630
Glide.get(CacheMonitoringActivity.this).clearMemory();
631
}
632
633
@Override
634
public void onTrimMemory(int level) {
635
// Trim cache based on system memory state
636
switch (level) {
637
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
638
Glide.get(CacheMonitoringActivity.this).clearMemory();
639
break;
640
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
641
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
642
Glide.get(CacheMonitoringActivity.this).trimMemory(level);
643
break;
644
}
645
}
646
});
647
}
648
}
649
```
650
651
### Preloading and Cache Warming
652
653
Preload images to warm up caches:
654
655
```java
656
public class CacheWarmingActivity extends AppCompatActivity {
657
658
public void preloadImages() {
659
List<String> imagesToPreload = Arrays.asList(
660
"https://example.com/image1.jpg",
661
"https://example.com/image2.jpg",
662
"https://example.com/image3.jpg"
663
);
664
665
// Preload with specific dimensions
666
for (String url : imagesToPreload) {
667
Glide.with(this)
668
.load(url)
669
.preload(200, 200);
670
}
671
672
// Preload with default dimensions
673
Glide.with(this)
674
.load(heroImageUrl)
675
.preload();
676
}
677
678
public void intelligentPreloading() {
679
// Preload based on user behavior patterns
680
List<ImageData> upcomingImages = getUserBehaviorPredictor().getNextLikelyImages();
681
682
for (ImageData imageData : upcomingImages) {
683
RequestOptions options = new RequestOptions()
684
.diskCacheStrategy(DiskCacheStrategy.DATA)
685
.priority(Priority.LOW); // Don't interfere with current requests
686
687
Glide.with(this)
688
.load(imageData.url)
689
.apply(options)
690
.preload(imageData.expectedWidth, imageData.expectedHeight);
691
}
692
}
693
}
694
```
695
696
## Best Practices
697
698
### Cache Strategy Guidelines
699
700
1. **Default Strategy**: Use `DiskCacheStrategy.AUTOMATIC` for most use cases
701
2. **Memory Management**: Monitor memory usage and trim caches during memory pressure
702
3. **Cache Keys**: Use consistent and meaningful cache keys with proper signatures
703
4. **Size Configuration**: Set appropriate cache sizes based on device capabilities
704
5. **Background Operations**: Always clear disk cache on background threads
705
706
### Performance Optimization Patterns
707
708
```java
709
public class CacheBestPractices {
710
711
// Optimal cache configuration for different scenarios
712
public static final RequestOptions PHOTO_GALLERY = new RequestOptions()
713
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) // Cache processed thumbnails
714
.priority(Priority.HIGH);
715
716
public static final RequestOptions USER_AVATARS = new RequestOptions()
717
.diskCacheStrategy(DiskCacheStrategy.ALL) // Cache everything for profiles
718
.circleCrop() // Consistent transformation
719
.signature(new ObjectKey("avatar_v2")); // Version cache key
720
721
public static final RequestOptions LARGE_IMAGES = new RequestOptions()
722
.diskCacheStrategy(DiskCacheStrategy.DATA) // Cache original, transform as needed
723
.format(DecodeFormat.PREFER_RGB_565); // Use less memory
724
725
public static final RequestOptions TEMPORARY_IMAGES = new RequestOptions()
726
.diskCacheStrategy(DiskCacheStrategy.NONE) // Don't cache temporary content
727
.skipMemoryCache(true);
728
}
729
```
730
731
This comprehensive caching system provides the flexibility and performance needed for efficient image loading while giving developers fine-grained control over memory and storage usage patterns.