CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-github-bumptech-glide--glide

A fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.

Pending
Overview
Eval results
Files

caching-strategies.mddocs/

Glide Caching Strategies System

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.

MemoryCache Interface

The memory cache provides fast access to recently loaded images, keeping them in RAM for immediate display:

public interface MemoryCache {
    /**
     * Gets the current size of the cache in bytes
     * @return Current cache size
     */
    long getCurrentSize();

    /**
     * Gets the maximum size of the cache in bytes
     * @return Maximum cache size
     */
    long getMaxSize();

    /**
     * Sets a multiplier for the cache size
     * @param multiplier Size multiplier (0.0-1.0)
     */
    void setSizeMultiplier(float multiplier);

    /**
     * Stores a resource in the cache
     * @param key The cache key
     * @param resource The resource to cache
     * @return Previous resource at key, or null
     */
    Resource<?> put(Key key, Resource<?> resource);

    /**
     * Retrieves a resource from the cache
     * @param key The cache key
     * @return Cached resource or null
     */
    Resource<?> remove(Key key);

    /**
     * Clears all entries from memory cache
     */
    void clearMemory();

    /**
     * Trims memory cache to specified level
     * @param level Trim level from ComponentCallbacks2
     */
    void trimMemory(int level);
}

DiskCache Interface

The disk cache provides persistent storage for images across application restarts:

public interface DiskCache {
    
    /**
     * Writer interface for writing cache entries
     */
    public interface Writer {
        /**
         * Writes data to the cache entry
         * @param file The file to write to
         * @return True if write successful
         */
        boolean write(File file);
    }
    
    /**
     * Factory interface for creating disk caches
     */
    public interface Factory {
        /**
         * Default disk cache directory name
         */
        String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
        
        /**
         * Default disk cache size in bytes (250 MB)
         */
        long DEFAULT_DISK_CACHE_SIZE = 250L * 1024 * 1024;
        
        /**
         * Creates a disk cache instance
         * @return New DiskCache instance
         */
        DiskCache build();
    }

    /**
     * Retrieves a file from the cache
     * @param key The cache key
     * @return Cached file or null
     */
    File get(Key key);

    /**
     * Stores data in the cache
     * @param key The cache key  
     * @param writer Writer to create cache entry
     */
    void put(Key key, Writer writer);

    /**
     * Removes entry from cache
     * @param key The cache key
     */
    void delete(Key key);

    /**
     * Clears all entries from disk cache
     */
    void clear();
}

DiskCacheStrategy Enum

Controls which versions of images are cached to disk:

public enum DiskCacheStrategy {
    /**
     * Caches all versions of images (original and transformed)
     * Provides fastest loading but uses most disk space
     */
    ALL,

    /**
     * Disables disk caching completely
     * Saves disk space but requires re-downloading/processing
     */
    NONE,

    /**
     * Caches only original source data
     * Useful for images that are transformed differently
     */
    DATA,

    /**
     * Caches only transformed/processed images
     * Good for consistent transformations
     */
    RESOURCE,

    /**
     * Intelligently chooses strategy based on image source
     * Default strategy - caches remote images but not local
     */
    AUTOMATIC;

    /**
     * Gets default strategy
     */
    public static DiskCacheStrategy getDefault() {
        return AUTOMATIC;
    }
    
    /**
     * Checks if strategy caches original data
     */
    public static boolean isDataCacheable(DiskCacheStrategy strategy) {
        return strategy == ALL || strategy == DATA || strategy == AUTOMATIC;
    }
    
    /**
     * Checks if strategy caches processed resources
     */
    public static boolean isResourceCacheable(DiskCacheStrategy strategy) {
        return strategy == ALL || strategy == RESOURCE || strategy == AUTOMATIC;
    }
}

LruResourceCache Implementation

The default memory cache implementation using Least Recently Used (LRU) eviction:

public class LruResourceCache implements MemoryCache {
    private final long maxSize;
    
    /**
     * Creates LRU cache with specified size
     * @param maxSize Maximum cache size in bytes
     */
    public LruResourceCache(long maxSize) {
        this.maxSize = maxSize;
    }

    @Override
    public long getCurrentSize() {
        // Implementation details
        return 0;
    }
    
    @Override
    public long getMaxSize() {
        return maxSize;
    }
    
    @Override
    public void setSizeMultiplier(float multiplier) {
        // Implementation details
    }
    
    @Override
    public Resource<?> put(Key key, Resource<?> resource) {
        // Implementation details
        return null;
    }
    
    @Override
    public Resource<?> remove(Key key) {
        // Implementation details
        return null;
    }
    
    @Override
    public void clearMemory() {
        // Implementation details
    }
    
    @Override
    public void trimMemory(int level) {
        // Implementation details
    }
    
    /**
     * Gets current number of entries
     */
    public int getCurrentEntryCount() {
        // Implementation details
        return 0;
    }
    
    /**
     * Gets eviction count since creation
     */
    public long getEvictionCount() {
        // Implementation details
        return 0;
    }
}

Disk Cache Factories

InternalCacheDiskCacheFactory

Creates disk cache in internal app storage:

public class InternalCacheDiskCacheFactory implements DiskCache.Factory {
    private final Context context;
    private final String diskCacheName;
    private final long diskCacheSize;
    
    /**
     * Creates internal cache factory with default settings
     * @param context Application context
     */
    public InternalCacheDiskCacheFactory(Context context) {
        this(context, DEFAULT_DISK_CACHE_DIR, DEFAULT_DISK_CACHE_SIZE);
    }
    
    /**
     * Creates internal cache factory with custom size
     * @param context Application context
     * @param diskCacheSize Cache size in bytes
     */
    public InternalCacheDiskCacheFactory(Context context, long diskCacheSize) {
        this(context, DEFAULT_DISK_CACHE_DIR, diskCacheSize);
    }
    
    /**
     * Creates internal cache factory with all custom parameters
     * @param context Application context
     * @param diskCacheName Cache directory name
     * @param diskCacheSize Cache size in bytes
     */
    public InternalCacheDiskCacheFactory(Context context, String diskCacheName, long diskCacheSize) {
        this.context = context;
        this.diskCacheName = diskCacheName;
        this.diskCacheSize = diskCacheSize;
    }

    @Override
    public DiskCache build() {
        // Implementation details
        return null;
    }
}

ExternalCacheDiskCacheFactory

Creates disk cache in external storage (SD card):

public class ExternalCacheDiskCacheFactory implements DiskCache.Factory {
    private final Context context;
    private final String diskCacheName;
    private final long diskCacheSize;
    
    /**
     * Creates external cache factory with default settings
     * @param context Application context
     */
    public ExternalCacheDiskCacheFactory(Context context) {
        this(context, DEFAULT_DISK_CACHE_DIR, DEFAULT_DISK_CACHE_SIZE);
    }
    
    /**
     * Creates external cache factory with custom directory
     * @param context Application context
     * @param diskCacheFolder Custom cache directory name
     * @param diskCacheSize Cache size in bytes
     */
    public ExternalCacheDiskCacheFactory(Context context, String diskCacheFolder, long diskCacheSize) {
        this.context = context;
        this.diskCacheName = diskCacheFolder;
        this.diskCacheSize = diskCacheSize;
    }
    
    /**
     * Creates external cache factory with all custom parameters
     * @param context Application context
     * @param diskCacheName Cache directory name
     * @param diskCacheSize Cache size in bytes
     */
    public ExternalCacheDiskCacheFactory(Context context, String diskCacheName, long diskCacheSize) {
        this.context = context;
        this.diskCacheName = diskCacheName;
        this.diskCacheSize = diskCacheSize;
    }

    @Override
    public DiskCache build() {
        // Implementation details
        return null;
    }
}

Cache Configuration

Memory Cache Configuration

Configure memory cache size and behavior:

public class CacheConfigurationActivity extends AppCompatActivity {

    public void configureMemoryCache() {
        // Get available memory
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        activityManager.getMemoryInfo(memoryInfo);
        
        // Use 1/8th of available memory for image cache
        long memoryCacheSize = memoryInfo.availMem / 8;
        
        // Configure through GlideModule
        class CustomGlideModule extends AppGlideModule {
            @Override
            public void applyOptions(Context context, GlideBuilder builder) {
                builder.setMemoryCache(new LruResourceCache(memoryCacheSize));
            }
        }
    }
    
    public void runtimeMemoryCacheControl() {
        // Clear memory cache
        Glide.get(this).clearMemory();
        
        // Trim memory cache based on system state
        Glide.get(this).trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
        
        // Get memory cache size info
        MemoryCache memoryCache = Glide.get(this).getMemoryCache();
        long currentSize = memoryCache.getCurrentSize();
        long maxSize = memoryCache.getMaxSize();
        
        Log.d("Cache", "Memory cache: " + currentSize + " / " + maxSize + " bytes");
    }
}

Disk Cache Configuration

Configure disk cache location and size:

public class DiskCacheConfigurationActivity extends AppCompatActivity {

    public void configureDiskCache() {
        class CustomGlideModule extends AppGlideModule {
            @Override
            public void applyOptions(Context context, GlideBuilder builder) {
                // Internal storage cache (100MB)
                long internalCacheSize = 100 * 1024 * 1024L;
                builder.setDiskCache(
                    new InternalCacheDiskCacheFactory(context, internalCacheSize)
                );
                
                // Or external storage cache (500MB)
                long externalCacheSize = 500 * 1024 * 1024L;
                builder.setDiskCache(
                    new ExternalCacheDiskCacheFactory(
                        context,
                        "my_app_cache",
                        externalCacheSize
                    )
                );
            }
        }
    }
    
    public void clearDiskCache() {
        // Must be called on background thread
        new Thread(new Runnable() {
            @Override
            public void run() {
                Glide.get(DiskCacheConfigurationActivity.this).clearDiskCache();
            }
        }).start();
    }
}

Cache Strategies Usage

Per-Request Cache Control

Control caching behavior for individual requests:

public class RequestCacheControlActivity extends AppCompatActivity {

    public void demonstrateCacheStrategies() {
        // Cache everything (original + transformed)
        Glide.with(this)
            .load(imageUrl)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .into(imageView);

        // Cache nothing to disk
        Glide.with(this)
            .load(imageUrl)
            .diskCacheStrategy(DiskCacheStrategy.NONE)
            .into(imageView);

        // Cache only original data
        Glide.with(this)
            .load(imageUrl)
            .diskCacheStrategy(DiskCacheStrategy.DATA)
            .into(imageView);

        // Cache only transformed result
        Glide.with(this)
            .load(imageUrl)
            .transform(new CenterCrop())
            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
            .into(imageView);

        // Skip memory cache but use disk cache
        Glide.with(this)
            .load(imageUrl)
            .skipMemoryCache(true)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .into(imageView);
    }
    
    public void cacheOnlyMode() {
        // Load only from cache, don't fetch if not cached
        Glide.with(this)
            .load(imageUrl)
            .onlyRetrieveFromCache(true)
            .into(imageView);
    }
}

RequestOptions with Cache Settings

Create reusable cache configurations:

public class CachePresets {
    
    // High performance: cache everything
    public static final RequestOptions PERFORMANCE_FOCUSED = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .skipMemoryCache(false);
    
    // Memory conscious: disk only
    public static final RequestOptions MEMORY_CONSERVATIVE = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
        .skipMemoryCache(true);
    
    // Bandwidth conscious: cache aggressively
    public static final RequestOptions BANDWIDTH_CONSERVATIVE = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .onlyRetrieveFromCache(false);
    
    // Testing/debugging: no caching
    public static final RequestOptions NO_CACHE = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .skipMemoryCache(true);
}

public class CachePresetsActivity extends AppCompatActivity {
    
    public void usePresets() {
        // Apply performance preset
        Glide.with(this)
            .load(imageUrl)
            .apply(CachePresets.PERFORMANCE_FOCUSED)
            .into(imageView);
            
        // Apply memory conservative preset
        Glide.with(this)
            .load(largeImageUrl)
            .apply(CachePresets.MEMORY_CONSERVATIVE)
            .into(imageView);
    }
}

Cache Key Generation

Custom Cache Keys

Control cache behavior with custom cache keys:

public class CacheKeyManagementActivity extends AppCompatActivity {

    public void customCacheKeys() {
        // Object-based cache key
        ObjectKey objectKey = new ObjectKey("user_profile_123");
        
        Glide.with(this)
            .load(profileImageUrl)
            .signature(objectKey)
            .into(profileImageView);
        
        // MediaStore signature for local files
        MediaStoreSignature mediaStoreSignature = new MediaStoreSignature(
            "image/jpeg",
            lastModified,
            ExifInterface.ORIENTATION_NORMAL
        );
        
        Glide.with(this)
            .load(localImageFile)
            .signature(mediaStoreSignature)
            .into(imageView);
        
        // Application version signature
        ApplicationVersionSignature appVersionSignature = ApplicationVersionSignature.obtain(this);
        
        Glide.with(this)
            .load(imageUrl)
            .signature(appVersionSignature)
            .into(imageView);
    }
    
    public void combinedSignatures() {
        // Combine multiple signatures
        List<Object> keyComponents = Arrays.asList(
            "user_id_123",
            "profile_version_5",
            System.currentTimeMillis() / (1000 * 60 * 60) // Hour-based cache
        );
        ObjectKey combinedKey = new ObjectKey(keyComponents);
        
        Glide.with(this)
            .load(profileUrl)
            .signature(combinedKey)
            .into(profileView);
    }
}

Advanced Cache Management

Cache Size Monitoring

Monitor and adjust cache sizes dynamically:

public class CacheMonitoringActivity extends AppCompatActivity {
    
    public void monitorCacheUsage() {
        MemoryCache memoryCache = Glide.get(this).getMemoryCache();
        
        // Get current statistics
        long currentSize = memoryCache.getCurrentSize();
        long maxSize = memoryCache.getMaxSize();
        int usagePercentage = (int) ((float) currentSize / maxSize * 100);
        
        Log.d("CacheStats", "Memory cache usage: " + usagePercentage + "% (" + currentSize + " / " + maxSize + " bytes)");
        
        // Adjust cache size based on memory pressure
        if (usagePercentage > 90) {
            memoryCache.setSizeMultiplier(0.8f); // Reduce by 20%
        } else if (usagePercentage < 50) {
            memoryCache.setSizeMultiplier(1.0f); // Full size
        }
    }
    
    public void adaptiveCacheManagement() {
        // Listen for memory pressure events
        registerComponentCallbacks(new ComponentCallbacks2() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {}
            
            @Override
            public void onLowMemory() {
                // Clear memory cache on low memory
                Glide.get(CacheMonitoringActivity.this).clearMemory();
            }
            
            @Override
            public void onTrimMemory(int level) {
                // Trim cache based on system memory state
                switch (level) {
                    case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
                        Glide.get(CacheMonitoringActivity.this).clearMemory();
                        break;
                    case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
                    case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
                        Glide.get(CacheMonitoringActivity.this).trimMemory(level);
                        break;
                }
            }
        });
    }
}

Preloading and Cache Warming

Preload images to warm up caches:

public class CacheWarmingActivity extends AppCompatActivity {
    
    public void preloadImages() {
        List<String> imagesToPreload = Arrays.asList(
            "https://example.com/image1.jpg",
            "https://example.com/image2.jpg", 
            "https://example.com/image3.jpg"
        );
        
        // Preload with specific dimensions
        for (String url : imagesToPreload) {
            Glide.with(this)
                .load(url)
                .preload(200, 200);
        }
        
        // Preload with default dimensions
        Glide.with(this)
            .load(heroImageUrl)
            .preload();
    }
    
    public void intelligentPreloading() {
        // Preload based on user behavior patterns
        List<ImageData> upcomingImages = getUserBehaviorPredictor().getNextLikelyImages();
        
        for (ImageData imageData : upcomingImages) {
            RequestOptions options = new RequestOptions()
                .diskCacheStrategy(DiskCacheStrategy.DATA)
                .priority(Priority.LOW); // Don't interfere with current requests
                
            Glide.with(this)
                .load(imageData.url)
                .apply(options)
                .preload(imageData.expectedWidth, imageData.expectedHeight);
        }
    }
}

Best Practices

Cache Strategy Guidelines

  1. Default Strategy: Use DiskCacheStrategy.AUTOMATIC for most use cases
  2. Memory Management: Monitor memory usage and trim caches during memory pressure
  3. Cache Keys: Use consistent and meaningful cache keys with proper signatures
  4. Size Configuration: Set appropriate cache sizes based on device capabilities
  5. Background Operations: Always clear disk cache on background threads

Performance Optimization Patterns

public class CacheBestPractices {
    
    // Optimal cache configuration for different scenarios
    public static final RequestOptions PHOTO_GALLERY = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.RESOURCE) // Cache processed thumbnails
        .priority(Priority.HIGH);
    
    public static final RequestOptions USER_AVATARS = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.ALL) // Cache everything for profiles
        .circleCrop() // Consistent transformation
        .signature(new ObjectKey("avatar_v2")); // Version cache key
    
    public static final RequestOptions LARGE_IMAGES = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.DATA) // Cache original, transform as needed
        .format(DecodeFormat.PREFER_RGB_565); // Use less memory
    
    public static final RequestOptions TEMPORARY_IMAGES = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.NONE) // Don't cache temporary content
        .skipMemoryCache(true);
}

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.

Install with Tessl CLI

npx tessl i tessl/maven-com-github-bumptech-glide--glide

docs

caching-strategies.md

error-handling-debugging.md

index.md

modules-configuration.md

request-configuration.md

request-management.md

targets-loading.md

transformations.md

transitions-animations.md

tile.json