This document outlines the comprehensive LRU (Least Recently Used) caching system implemented in the Talkeys Android application to improve performance, reduce network calls, and enhance user experience.
- LruCache.kt - Generic thread-safe LRU cache implementation
- CacheManager.kt - Centralized cache management with different cache instances
- ImageCache.kt - Specialized image caching with memory and disk storage
- CacheInvalidator.kt - Smart cache invalidation utilities
- CacheUsageExample.kt - Comprehensive usage examples and best practices
- Events Cache: 100 items, 30-minute TTL
- Event Details Cache: 50 items, 60-minute TTL
- User Profile Cache: 50 items, 15-minute TTL
- User Events Cache: 20 items, 10-minute TTL
- Recent Activity Cache: 20 items, 5-minute TTL
- Memory Cache: 10MB LRU cache for quick access
- Disk Cache: 50MB persistent storage with automatic cleanup
- Features: Size optimization, automatic compression, expired file cleanup
// Cache-enabled methods with optional force refresh
suspend fun getAllEvents(forceRefresh: Boolean = false): Result<List<EventResponse>>
suspend fun getEventById(eventId: String, forceRefresh: Boolean = false): Result<EventResponse>// All methods now support caching with force refresh option
suspend fun getUserProfile(forceRefresh: Boolean = false): Result<UserProfileResponse>
suspend fun getUserEvents(..., forceRefresh: Boolean = false): Result<UserEventsResponse>
suspend fun getRecentActivity(..., forceRefresh: Boolean = false): Result<Map<String, Any>>fetchAllEvents(forceRefresh: Boolean = false)- Load events with cache supportfetchEventById(eventId: String, forceRefresh: Boolean = false)- Load specific eventrefreshEvents()- Force refresh bypassing cache
- Thread-safe operations with coroutines and mutex
- TTL-based expiration with automatic cleanup every 5 minutes
- LRU eviction when cache size limits are reached
- Memory optimization for images with size constraints
// Clear specific caches
CacheManager.eventsCache.clear()
CacheManager.clearUserCaches() // Clear user-specific data
CacheManager.clearAllCaches() // Nuclear option
// Check cache status
val stats = CacheManager.getCacheStats()
val hasData = CacheManager.eventsCache.containsKey("key")// Automatic invalidation based on data changes
CacheInvalidator.invalidateByDataType(DataChangeType.EVENT_CREATED)
CacheInvalidator.invalidateByDataType(DataChangeType.USER_PROFILE_UPDATED)
CacheInvalidator.invalidateEventCache("specific-event-id")// ViewModels automatically use caching
viewModel.fetchAllEvents() // Uses cache if available
viewModel.refreshEvents() // Forces fresh dataval imageCache = ImageCache.getInstance(context)
val bitmap = imageCache.getImage(imageUrl) // Automatic caching
val resized = imageCache.getImage(imageUrl, maxWidth = 300, maxHeight = 200)try {
val result = repository.getAllEvents()
// Handle result
} catch (e: Exception) {
// Even if API fails, cached data might still be available
val cached = CacheManager.eventsCache.get(CacheManager.Keys.ALL_EVENTS)
// Fallback to cached data or show error
}- Reduced API calls by serving cached data
- Faster load times for frequently accessed data
- Offline capability with cached data availability
- Efficient memory usage with LRU eviction
- Automatic cleanup of expired entries
- Size-constrained caches prevent memory bloat
- Instant data loading from cache
- Smooth navigation between screens
- Reduced loading indicators for cached content
- Time-based: TTL expiration for all caches
- Event-driven: Smart invalidation on data changes
- Size-based: LRU eviction when limits reached
- User logout: Clear all user-specific caches
- Data updates: Invalidate related caches
- Force refresh: Bypass cache for fresh data
val stats = CacheManager.getCacheStats()
// Returns: memory usage, hit/miss ratios, cache sizes
val imageStats = ImageCache.getInstance(context).getCacheStats()
// Returns: memory/disk usage, file countsAll cache operations are logged with appropriate tags:
LruCache: Core cache operationsCacheManager: Cache management operationsImageCache: Image caching operationsCacheInvalidator: Invalidation operations
✅ Use caching by default for better UX ✅ Provide refresh functionality that bypasses cache ✅ Invalidate caches when data changes ✅ Monitor cache statistics in development ✅ Use appropriate TTL based on data freshness needs
❌ Don't cache sensitive user data without encryption ❌ Don't ignore cache invalidation on data updates ❌ Don't set cache sizes too large (memory constraints) ❌ Don't rely solely on cached data for critical operations
- All repository methods maintain backward compatibility
- ViewModels updated with optional
forceRefreshparameters - No breaking changes to existing API calls
- Total cache memory usage: ~15MB for data + 10MB for images
- Automatic cleanup prevents memory leaks
- Size limits prevent excessive memory usage
- Encrypted caching for sensitive data
- Network-aware caching (WiFi vs mobile data)
- Predictive caching based on user behavior
- Cache warming strategies for critical data
This caching implementation significantly improves the Talkeys app's performance while maintaining data freshness and providing excellent user experience.