Overview
Effective memory management is crucial for Android applications that load a large number of images as it significantly impacts the application's performance.
By utilizing a combination of memory cache and disk cache to cache images, performance of the application can be greatly improved in situations where large numbers of images are being loaded.
For more information about cache, please refer to this resource.
Memory cache: Cache images on your device's RAM memory.
Disk cache: Because the RAM memory is not too large in size, the data cache in RAM will quickly fill up. Therefore disk cache is used in this case and helps to reduce the load time of images that are not available in memory cache.
Challenge
Although your gallery in the cloud contains 4000 images with an average size of 1.5MB, totaling 6GB in size, your device has only 150MB of available RAM.
Question: How to display all images smoothly?
When developing for Android, some issues that may arise when acquiring images include:
A decision was made to utilize an image caching library.
Learn about the DisplayingBitmaps Library
Github: android-DisplayingBitmaps
Image Cache
The image caching mechanism stores accessed images in cache, which enhances the display speed when retrieving the same image subsequently.
How image caching works
The main components of the image caching library are:
Image fetcher
Image fetcher works like this:
Popular Image caching strategies:
LRU is the most common caching strategy.
LRU algorithm
LRU stands for Least Recently Used and is a cache eviction algorithm used to determine which data should be removed from the cache when the cache reaches its maximum size. The LRU algorithm removes the least recently used data from the cache, which is considered to be the data that has not been accessed for the longest period of time. By removing the least recently used data, the LRU algorithm makes room for new data to be cached, improving cache performance.
Disk cache strategy
Initialize DiskLruCache object in external memory such as SDCard. How much memory should be set: 10MB?
private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
public int diskCacheSize = DEFAULT_DISK_CACHE_SIZE;
if (getUsableSpace(diskCacheDir) > mCacheParams.diskCacheSize) {
try {
mDiskLruCache = DiskLruCache.open(
diskCacheDir, 1, 1, mCacheParams.diskCacheSize);
} catch (final IOException e) {
mCacheParams.diskCacheDir = null;
}
}
Memory cache strategy
Initialize the LruCache object with the specified amount of RAM. Set memory cache size based on maximum available VM memory: 25%?
private LruCache<String, BitmapDrawable> mMemoryCache;
// Set memory cache size is 25% of the max available VM memory
cacheParams.setMemCacheSizePercent(0.25f);
// Initialize memory cache
mMemoryCache = new LruCache<String, BitmapDrawable>(mCacheParams.memCacheSize);
Image optimization
If you load a large image into RAM memory as it is, it will not be efficient, so reduce it to a smaller size and load it into RAM memory.
For example, an image with a resolution of 2048x1536 is scaled down by a factor of 4 to produce an image of approximately 512x384. Loading this into memory uses 0.75MB for the full image instead of 12MB.
Details of how image caching works
Points to note
As the cache is stored in memory, the cached version of an image may be displayed instead of the updated version, leading to potential issues where the new image is not displayed.
Solutions: